Many times you write a Windows program, you need to combine multithreading, use the following code to create and start a new thread in .NET.
Public void threadproc ();
Thread thread = New Thread (New ThreadStart (threadproc);
Thread.isbackground = true;
Thread.start ();
But many times, in the new thread, we need to interact with the UI, and we do not allow us to do it directly in .NET. You can refer to the description in MSDN:
"Windows Form" uses a single-threaded unit (STA) model because the "Windows Form" is based on the Win32 window, while the Win32 window is in essentially unit thread. The STA model means that the window can be created on any thread, but once the window cannot switch the thread, and all of its function calls must occur on its creation thread. In addition to the Windows Form, the class in the .NET Framework uses the free thread model.
The STA model requires any way to be on the control from the controlled non-creating threads must be sealed (on it) the creation thread of the control. Base class Control provides a number of methods for this purpose (Invoke, BeginInvoke, and EndInvoke). Invoke generation synchronization method call; BeGinInvoke generates asynchronous method calls.
The controls in the Windows Form are bound to a specific thread without having thread security. Therefore, if the control is called from another thread, an Invoke method of the control must be used to encapsulate the call to the appropriate thread.
As seen, we must call the Invoke method, and BeginInvoke can be considered as an asynchronous version of Invoke. The calling method is as follows:
Public Delegate void OutdeLegate (String text);
Public void outtext (String text)
{
TXT.APPpendText (Text);
TXT.APPpendText ("/ t / n");
}
Outdelegate outdelegate = new outdelegate (OutText);
THIS.BEGININIVOKE (Outdelegate, New Object [] {text});
If we need to operate in another thread, we need a function similar to OutText, there is also a delegated delegate of this function, of course, it is displayed in custom, there are many other types of delegates in. It can be used directly, not required. For example: MethodInvoker and EventHandler, these two types of entrusted function appearance are fixed, MethodInvoker is a delegate of Void function () type, and EventHandler is a delegation of Void Function (Object, Eventargs), the first non-support parameter, The parameter type and quantity of the second in seconds are fixed, and these two commission can be easily called, but lack of flexibility. Note that the object in front of BeGinInvoke is this, which is the main thread. Now introduce Control.InvokeRequired, Control is the base class for all controls, and the description of this attribute MSDN is:
Get a value indicating whether the Supplier must call the Invoke method when the control is called, because the call is located in the thread other than the thread where the control is created.
This property can be used to determine if the Invoke method must be called, which is useful when you don't know what the thread has a control. That is to say, by judging that INVOKEREQUIRED can know if it is necessary to call some of the method of calling the current control, so you can modify the OutText function:
Public Delegate void OutdeLegate (String text);
Public void outtext (String text)
{
IF (txt.invokerequired)
{
Outdelegate outdelegate = new outdelegate (OutText);
THIS.BEGININIVOKE (Outdelegate, New Object [] {text});
Return;
}
TXT.APPpendText (Text);
TXT.APPpendText ("/ t / n");
}
Note that the function here is not returned. If there is a return, you need to call the Invoke or endInvoke to get the result of the return, do not lose the return value due to packaging. If the call is not completed, INVOKE and EndInvoke will cause blocking.
Now if I have a thread function as follows:
Public void threadproc ()
{
For (int i = 0; i <5; i )
{
OutText (I.toString ());
Thread.sleep (1000);
}
}
If the number of times the loop is large, or leak thread.sleep (1000); then your UI will stop responding, do you want to know the cause? Take a look at the objects in Beginvoke, yes, this is the main thread. When your main thread is constantly calling OutText, the UI will certainly stop responding.
Creating a new thread in the previous VC requires calling the AFXBEGINTHREAD function, the first parameter in this function is the address of the thread function, and the second parameter is a pointer type with LPVOID, which will pass to the thread function. Now we have no way to use this method to deliver parameters. We need to package the parameters and thread functions pass to the thread into a separate class, then initialize the parameters required for the thread in this class constructor, and then pass the thread function of the instance to the constructor of the Thread class. The code is approximately as follows:
Public Class ProccoSs
{
Private String Procparameter = ""
Public Proclass (String parameter)
{
Procparameter = parameter;
}
Public void threadproc ()
{
}
}
Proclass threadProc = New Procclass ("Use thread class");
Thread thread = New Thread (New Threadstart (ThreadProc.ThreadProc);
Thread.isbackground = true;
Thread.start ();
That is, a middle class is required to deliver the parameters required for the thread.
So what should I do if my thread needs to be parameters? You can modify the code:
Public Class ProccoSs
{
Private String Procparameter = ""
Private form1.outdelegate Delg = NULL;
Public Procco (String Parameter, Form1.outDelegate Delg) {
Procparameter = parameter;
THIS.DELG = DELG;
}
Public void threadproc ()
{
Delg.BeginInvoke ("Use ProccoS.ThreadProc ()", NULL, NULL);
}
}
Proclass threadproc = New Proclass ("Use Thread Class", New OutdeLeGate
Thread thread = New Thread (New Threadstart (ThreadProc.ThreadProc);
Thread.isbackground = true;
Thread.start ();
Here is just some of my understanding, if there is any mistake or improper place, welcome.