Threaded Controls

I'm a little confused on how to show a progressBar with style continious on a seperate thread. Do I need to create the progressBar at runtime...or can I pop one on the form and just invoke it Style Continious can just be set in properties...with nothing really to do in the threadproc...know what I mean

My form is also getting very "crowded"....mucho hidden panels groupbox, etc. Rather create at runtime and just bringtofront....let it run...and then abort when finished.

TIA




Answer this question

Threaded Controls

  • MikeBlig

    You can't touch your a control with a thread other than the thread that created it.

    Create the ProgressBar and add it to the Controls collection using the same thread that created the form.

    There are a number of good articles on safe multi-threading with Windows Forms here: http://www.sellsbrothers.com/news/showTopic.aspx ixTopic=1707



  • Radu Motisan

    You can add the control dynamically, at runtime. See "To add a control to a form programmatically" in this doc. You'll still need to make sure you don't touch the control from a different thread.



  • Tomasz007

    Getting a cross thread exception..

    ProgressBar prog;

    Thread timerThread;

    private void Client_Shown(object sender, EventArgs e)

    {

    timerThread = new Thread(new ThreadStart(ThreadProc2));

    timerThread.IsBackground = true;

    timerThread.Start();

    }

    public void ThreadProc2()

    {

    prog = new ProgressBar();

    prog.Style = ProgressBarStyle.Continuous;

    prog.Location = new Point(25, 25);

    this.Controls.Add(prog);

    }



  • Wellnow

    Im aware of that...however...I need the progressBar in its own thread...the form will be very "busy".

  • mohasad

    As Scott mentioned (MVP ain't just initials)....creating the second form will lead to problems.

    Runs fine, for some reason, in the IDE....but compiled, using .Abort to dump the "form" will every now and then throw an unhandled exception.

    Next step is toying with .isbackground and interupt. Or hiding the second form before closing it.



  • Boris Mueller

    Well, you can't get around the thread affinity of the Form, there is no way to add that control to the Controls collection unless you do so with the same thread that created the Form.

    An alternative is to create a second Form with a ProgressBar using the second thread, and set up a message pump with Application.Run, but personally I'd try hard to avoid that scenario.

    Without knowing more about the project I can't offer specific suggestions, but I'd try hard to move the heavy processing off the primary UI thread and into the background. You also might be able to pump messages with DoEvents now and then to keep the UI updated, but this approach also has issues.



  • Omarat56

    Did manage to hack together a solution creating another form in a seperate thread.

    Set the Form TransparencyKey to From backgroundcolor and used Marquee style.



  • dzn

    Thanks Scott. Looks like I got meself in a corner here. Just assumed all along that there had to be a way to invoke this...never checked.

    Most of the work is done in form load and form shown with a couple of threads. When the form is shown it would have been nice to have a visual of "not complete"...as a sometimes lenghty operation then begins with the UI updated with a couple of labels. The form is rather large...and the label updating doesn'nt quite get it, visually.

    Live and learn. Thanks again.



  • Deasun

    Just to clarify, if you want to operate on a control from a worker thread, you can always use the Control.Invoke method as follows:

    new Thread(delegate() {

    ...do stuff in my worker thread...

    myForm.Invoke((ThreadStart)delegate() {

    ...do stuff to the progress bar, or add a new progress bar to the form...

    });

    }),Start();

    This technique (or something like it) is usually the preferred method. The Invoke method executes the code on the control's thread, so you don't get the thread exception, but it does so syncrhonously, so its similar to executing it on your worker thread. You can also use the BeginInvoke method to cause it to execute asynchronously so that your worker thread continues working the form to execute your delegate.


  • Mekon2

    Right, we've covered that, I think. In cablehead's case the UI thread was busy and not pumping messages. Invoke and BeginInvoke can't update the UI if the thread isn't pumping messages to the controls.

  • Threaded Controls