Cross-thread update of WinForm controls in C # invoke

Source: Internet
Author: User

Objective:

Use WinForm (C #) to build a user interface, a progress bar and a button to start the progress bar, stop the update when the progress is complete

Example:

650) this.width=650; "src=" Http://s4.51cto.com/wyfs02/M02/76/19/wKioL1ZKiOLAiXwDAAAv3UpvmTg539.png "title=" 2015-11-17 (1). png "alt=" Wkiol1zkiolaixwdaaav3upvmtg539.png "/>


Realize:

To set a loop in a button event, update the progress bar

private void Btnprogress_click (object sender, EventArgs e) {for (int II = 0; II <; ii++)                {progressBar1.Value = II + 1;            Thread.Sleep (100); }        }


Question 1:

The progress bar is updated well, but the window is stuck during the update because the button event is in the window thread and execution does not respond to any other messages in the loop body


Resolution 1:

Add Application.doevents () to the loop body

        private void  Btnprogress_click (object sender, eventargs e)         {             for  (int ii = 0;  ii < 100; ii++)              {                 Application.doevents ();                 progressBar1.Value = ii + 1;                 thread.sleep (;       )      }        } 


Question 2:

This approach allows window events to share thread time resources, but individual execution fragments are still executed sequentially, with longer execution fragments having significant impact on other events.

Thread.Sleep (100) can be assumed to be a complex logic or calculation, and if sleep (100) is changed to sleep (1000) or greater, the effect of the user interface does not significantly improve on problem 1.


Resolution 2:

The introduction of additional threads, which enable the control of progress on its own, is actually a separation of the time-consuming logical or computational threads from the execution (time) resources of the user interface.

        public void threadprogress ()          {            while  ( PROGRESSBAR1.VALUE&NBSP;&LT;&NBSP;100)              {                 progressbar1.value++;                 thread.sleep (;            } )        }                 private void btnprogress_click (Object sender, eventargs  e)         {                  thread thprog = new thread (threadprogress);                 thprog. Start ();         }

This code can be compiled, but cannot be executed, and will run into InvalidOperationException because the state update of the WinForm control can only be done within the user interface thread, which is actually the thread that created the form (and the same as the response clicked event). You can now track the solution given by the exception help document, how To:make thread-safe Calls to Windows Forms controls describes the complete problem definition and resolution.

WinForm the cross-thread update of a control to use the space itself or the Invoke method within the thread, the invoke parameter is assigned using the delegate function. The behavior of the thread needs to be modified.

        public delegate void setprogress (INT&NBSP;PVV);                 void  Guisetprogressmustininvokeoruithread (INT&NBSP;PVV)         {             progressBar1.Value = pvv;         }                 void delesetprogress (INT&NBSP;PVV)          {            if  ( progressbar1.invokerequired)             {                 SetProgress  Spself = new setprogress (GuisetprogRessmustininvokeoruithread);                 progressbar1.invoke (SPSELF,&NBSP;NEW&NBSP;OBJECT[]&NBSP;{&NBSP;PVV&NBSP;});             }        }                 public  Void threadprogress ()         {             while  (progressbar1.value < 100)              {                 delesetprogress (progressbar1.value + 1);                 thread.sleep (;  )           }        } 

The above code is the solution in the document disassembly method, Delesetprogress determined to be called by the external thread , it needs to put the actual update through the Invoke function back to the interface thread, The execution guisetprogressmustininvokeoruithread is performed using the delegate variable.

The explanation for invoke in the Help document is

Executes a delegate on the thread that owns the control ' s underlying window handle

This ensures execution in the interface thread, and of course the execution fragment is part of the Guisetprogressmustininvokeoruithread , separating the complex logic from the interface update implementation.


Question 3:

The above code will work fine, but when you close the window during the update process, you will encounter system.objectdisposedexception. The reason is that the user thread is still trying to update the progress bar after the window and space are freed.


Resolution 3:

Several options are available, forcing the end of the user thread before the window closes, waiting for the user to end the logic before the window closes, or more complex thread management logic.

This waits for the thread to end, the thread needs to remain in the member, and the user logic sets the flag to ensure the security of calls between threads.

        private Thread thProgress = null;                 public void  threadprogress ()         {             ...             thProgress = null;        }                 private void formprogress_ FormClosing (object sender, formclosingeventargs e)          {            while  (thprogress !=  null)             {                 application.doevents ();                 thread.sleep (0);             }        }                 private void btnprogress_click ( Object sender, eventargs e)         {             if  (thprogress == null)              {                 thprogress = new thread (threadProgress);                 thprogress.start ();             }        } 



This article is from the "Technology Change Life" blog, please be sure to keep this source http://btvnlue.blog.51cto.com/9578271/1713391

Cross-thread update of WinForm controls in C # invoke

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.