C # WinForm Multithreading (iii) Control.Invoke

Source: Internet
Author: User

Let's take a look at some of the problems we need to pay attention to when using invoke in Windows Form software.

First, what kind of operations need to consider using multithreading? The general rule is that the thread responsible for interacting with the user (the UI thread) should be smooth and should be considered for multithreading when the API invoked by the UI thread can cause blocking times exceeding 30 milliseconds, such as accessing ultra-slow peripherals such as CD-ROM, making remote calls, and so on. Why is it 30 milliseconds? The concept of 30 milliseconds is a hysteresis that can be perceived by the human eye, approximately equal to the length of a frame in a movie, and not more than 100 milliseconds.

Second, the most convenient and simple multithreading is the use of thread pooling. The easiest way to run code through thread-constructor threads is to use an asynchronous delegate invocation. Note that the delegate invocation is usually done synchronously, use the BeginInvoke method so that the method you want to call is queued to the line constructor wait for processing, and the process of the program is immediately returned to the caller (here is the UI thread), and the caller does not block.

Looking at the following example, we find that it is not very complicated to execute code asynchronously using the thread pool, where we use the System.Windows.Forms.MethodInvoker delegate for asynchronous invocation. Note that the MethodInvoker delegate does not accept the method arguments, and if you need to pass parameters to methods that are executed asynchronously, use a different delegate, or you need to define it yourself.

Code

Summarize the above method, for the UI thread is actually: 1, make a call, 2, return immediately, the specific operation process is ignored, so that the UI thread will not be blocked. This approach is important and we'll go into it in more detail below. In addition to the methods above, there are other ways to use the thread pool, but you can also create threads yourself if you are happy.

Third, using multithreading in Windows Form, one of the most important considerations is that, in addition to the thread that creates the control, you should never invoke the members of the control in any other thread (with the exception of very few exceptions), that is, the control belongs to the thread that created it and cannot be accessed from within other threads. This applies to all controls that derive from System.Windows.Forms.Control (and therefore can be said to be almost all controls), including the form control itself. Extrapolate, it is easy to conclude that the control's child controls must be created by the thread that created the control, such as a button on a form, such as a thread that creates a form, so that all the controls in one window actually live in the same thread. In actual programming, most of the software's approach is to make the same thread responsible for all the controls, which is what we call the UI thread. Look at the following example:

This is a label control defined by the UI thread
Private Label lblstatus;
.
The following methods do not execute on the UI thread
private void Runsonworkerthread () {
Dosomethingslow ();
Lblstatus.text = "finished!"; This is wrong.
}

We would like to remind you that many people just start out using the above method to access controls that are not on the same line thread (including the author himself), and there seems to be no problem with the 1.0. Net Framework, but this is fundamentally wrong, and, worse, the programmer will not get any errors here. The pain of Windows Form multithreaded programming is that you will find other errors in the first place. I try to spend a lot of time to debug their splash window suddenly disappear, the result or failure: the author in the process of software guidance, with another line thread created a splash window to display the Welcome information, Then try to write the boot state of the main thread directly to the control on the Splash window, start OK, but after a while the splash window disappears.

To understand this, we should note that sometimes even if we do not explicitly create a thread with System.Threading.Thread, we may have implicitly created threads (from line constructor) because of the BeginInvoke method of using the asynchronous delegate. In this line thread also cannot invoke the members of the control created by the UI thread.

Finally, because of the above limitations, we may find it inconvenient, indeed, when we use a newly created thread to perform some time-spent operations, how do we know the progress of the operation and reflect it to the user through the UI? There are many ways to solve this! For example, users familiar with multithreaded programming will soon think that we are using some low-level synchronization methods, the worker thread saves the state to a synchronization object, let the UI line Cheng (Polling) The object and feedback to the user. However, this is quite a hassle, in fact, do not have to do so, the control class (and its derived class) object has an Invoke method is very special, this is one of the few members not restricted by the thread. As we said before, never invoke a member of a control that is not created by this thread in any other thread, and say "only very few exceptions", this invoke method is one of the very few cases----the Invoke method can be called from any thread. Let's explain the Invoke method below.

The parameters of the Invoke method are simple, a delegate, a parameter table (optional), and the main function of the Invoke method is to help you invoke the method specified by the delegate on the UI thread (that is, the thread that created the control). The Invoke method first checks that the calling thread (that is, the current thread) is not the UI thread, and if so, directly executes the method that the delegate points to, if it is not, it switches to the UI thread and then executes the method that the delegate points to. If the current thread is not a UI thread, invoke blocks until the method that the delegate points to executes, and then switches back to the thread that issued the call (if necessary). Note that when you use the Invoke method, the UI thread cannot be in a blocked state. The following MSDN notes about the Invoke method:

There are four methods on the control that can be safely invoked from any thread: Invoke, BeginInvoke, EndInvoke, and CreateGraphics. For all other method calls, you should marshal the call to the control's thread using one of the call (Invoke) methods.
The delegate can be an instance of EventHandler, in which case the sender parameter will contain the control, and the event arguments will contain eventargs.empty. A delegate can also be an instance of MethodInvoker or any other delegate that takes a void argument list. Calling EventHandler or MethodInvoker delegates is faster than calling other types of delegates. ”

Well, when you're done with invoke, by the way BeginInvoke, there's no doubt that this is the asynchronous version of Invoke (Invoke is synchronous), But let's not confuse the BeginInvoke with the System.Windows.Forms.MethodInvoker delegate above, both of which use a different thread to do the work, but the BeginInvoke method of the control always uses the UI thread, while the other asynchronous delegate invocation method uses the Thread constructor threads. Relative to invoke, using BeginInvoke a little trouble, but still the sentence, asynchronous than synchronous effect is better, although more complex. For example, a synchronization method might have a deadlock situation in which a worker thread is blocked by invoking the method of the UI line thread through invoke synchronization, and what if the UI thread is waiting for a worker thread to do something? Therefore, you should use asynchronous methods whenever possible when you are able to use asynchronous methods.

Let's use the knowledge we've learned to rewrite the simple example above:

Code

C # WinForm Multithreading (iii) Control.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.