First, preface
Multi-threaded operation has always been a common programming operation, master the basic operation can make the program run more effective. This article does not beg chatty, just will my own work often uses the multithreading operation to make a classification and summary. You can see it when you have a bad memory. This article refers to a number of wonderful blog posts in the garden, at the end of the article will be posted specific sources, thank them for their selfless dedication.
Second, about the thread
(1) Why threads are used:
You can use threads to isolate code from other code to improve application reliability;
You can use threads to simplify coding;
Threads can be used to implement concurrent execution.
(2) the relationship between the process, the application domain, and the thread:
Process is a basic concept in Windows systems that contains the resources required to run a program. Processes are relatively independent, and one process cannot access the data of another process (unless distributed computing is used), and the failure of one process to run does not affect the operation of other processes, and Windows systems use processes to divide the work into separate areas. A process can be understood as a basic boundary of a program.
An application domain (AppDomain) is a logical area in which a program runs, and it can be considered a lightweight process. NET assemblies are run in an application domain, a process can contain multiple application domains, and an application domain can contain multiple assemblies. Contains one or more context contexts in an application domain, using the context CLR to place the state of certain special objects in different containers.
Thread is the basic unit of execution in a process, and the first thread that executes at the process entrance is considered the thread of the process.
The diagram is as follows:
Third, Thread
thread may be the most multithreaded class that is used in addition to the task. General usage:
//One threadThread thread =NewThreadStart (functiion); thread. Start ();//Thread.JoinThread Threada =NewThread (Delegate() {//Do something}); Thread threadb=NewThread (Delegate() {//Do something; Threada.join (); //Do Another thing}); //Start ThreadThreada.start (); Threadb.start ();//At first, two threads run alternately with each other, and when thread B runs to thread A's join, thread a executes, and thread B resumes execution. You can understand that as overtaking, the first two don't give a hand, when join, thread a overtaking thread B
Iv. ThreadPool
because of the cost of creating and destroying threads, excessive use of threads can cause memory resources to be wasted, and the concept of a thread pool is introduced for performance reasons. The thread pool maintains a request queue, the thread pool's code extracts the task from the queue, and then it is delegated to a thread pool for execution, and the threads are not destroyed immediately after execution, so that tasks can be performed in the background and the overhead of thread creation and destruction can be reduced.
If a thread has a very long time, there is no need to use a thread pool (not a long time operation, but not.) , and we can't control the thread pool start, suspend, and abort.
ThreadPool.QueueUserWorkItem (Function,parameter);
Span style= "font-size:14pt" >
Span style= "font-size:14pt" > < Span style= "COLOR: #ff0000" > task is the most multithreaded way I use, generally using the following methods: < Span style= "COLOR: #000000" >&NBSP;&NBSP;
// one task var task = new Task (() =>{
// do something
}); task. Start ();
// Task one by one
var task = new Task (() =>{
// do something
});
Task Task2 = task. ContinueWith (() =>{
// do something
});
Task. Start ();
//Many tasksvartasks =NewTask[packcount];//multithreaded Tasks for(intindex =0; Index < Packcount; index++){ intThreadindex =index; varTask =NewTask (() = { //Do Something} }); Tasks[threadindex]=task; Task. Start ();} Task.waitall (tasks); //wait for all threads to complete//Task.waitany (tasks);//wait for a thread to finish executing the main program
Task.factory
Task.Factory.StartNew (() =>{//Do something });
Vi. Invoke, BeginInvoke, DynamicInvoke
The main explanation here is the various invoke under delegate.
invoke (delegate method execution in the same thread as the call )
Delegate void New mydelegate (Function);d el. Invoke (); // use the Invoke method to a delegate
BeginInvoke (it fetches an idle thread from the thread pool to delegate the execution method)
A case: Use iasyncresult.iscompleted to determine if the child thread has finished executing
Delegatenew= Del. BeginInvoke (parameter,null,null); // if the branch thread is not completed while (! result. iscompleted) { // the main thread do another thing= var data is the result of a Function with parameter
B Case: Use IAsyncResult.AsyncWaitHandle.WaitOne (timeout) to determine if the child thread is complete
DelegateT mydelegate (); MyDelegate del=Newmydelegate (Function); IAsyncResult result= Del. BeginInvoke (parameter,NULL,NULL);//if the branch thread is not completed while(!result. Asyncwaithandle.waitone (inttimeout)) { //The main thread do another thing}t Data=del. EndInvoke (result); //var data is the result of a Function with parameter
Case C: Use WaitHandle.WaitAll (waithandle[],timeout) to determine if the child thread has finished executing
DelegateT mydelegate (); MyDelegate del=Newmydelegate (Function); IAsyncResult result= Del. BeginInvoke (parameter,NULL,NULL); Waithandle[] Waithandlelist=Newwaithandle[] {result. AsyncWaitHandle,........}; while(! WaitHandle.WaitAll (Waithandlelist,inttimeout)) { //The main thread do another thing}t Data=del. EndInvoke (result); //var data is the result of a Function with parameter
D: Using a polling method to detect the state of an async method is cumbersome and inefficient, and a callback function is required for this purpose. The main thread can do its own thing with peace of mind, and the asynchronous thread executes the callback function after it completes the operation. The callback function is still on the asynchronous thread, not the main thread.
DelegateT mydelegate (); MyDelegate del=Newmydelegate (Function); IAsyncResult result= Del. BeginInvoke (parameter,NewAsyncCallback (Callbackfunction),Object);.... Mainthread Dosomethng ...Static voidcallbackfunction (IAsyncResult result) {AsyncResult _result=(AsyncResult) result; MyDelegate del=(mydelegate) _result. AsyncDelegate; T Data=del. EndInvoke (_result); T1 Objectreciever= (T1) result. AsyncResult;//Object=result. AsyncResult}
DynamicInvoke:
Similar to Delegate.invoke, synchronous, and the same thread, the only difference is that it is late binding to invoke the delegate method, so the time cost is large.
Work Example: An exception occurred in WPF: "The calling thread cannot access this object because another thread owns the object." "
Scenario A: Assuming that the code for the exception occurred in the Xaml.cs file, then Dispatcher.invoke is sufficient.
Case B: Assuming that the code for the exception occurred in a. cs file, there is a trick on the stack overflow:
1 Private voidRaiseeventonuithread (Delegate theevent,Object[] args)2 {3 foreach(Delegate Dinchtheevent.getinvocationlist ())4 {5ISynchronizeInvoke Syncer = D.target asISynchronizeInvoke;6 if(Syncer = =NULL)//static function is null
7 {8 D.dynamicinvoke (args);9 }Ten Else One { A Syncer. BeginInvoke (d, args); executes the delegate asynchronously on the thread that created the object - } - } the}
References:
"1" http://blog.sina.com.cn/s/blog_5a6f39cf0100qtzf.html
"2" http://www.cnblogs.com/slikyn/articles/1525940.html
"3" http://kb.cnblogs.com/page/130487/#t3
"4" http://blog.csdn.net/soft_123456/article/details/38819877
"5" http://www.cnblogs.com/laoyur/archive/2011/04/14/2016025.html
"6" http://blog.csdn.net/cselmu9/article/details/8274556
"7" Http://stackoverflow.com/questions/1698889/raise-events-in-net-on-the-main-ui-thread
C # Intermediate-Common multithreaded operations (continuous update)