Multi-thread programming in Visual C #

Source: Internet
Author: User

C # is a general development tool for the. Net platform. It can build all. Net applications. All threads in. Net run in the application domain (AppDomain), which may remind you of Win32 processes. In fact, they are quite different. The application domain provides a secure and universal processing unit, which can be used by the Common Language Runtime Library to isolate applications. Note that. in. Net, application isolation is the application domain rather than the process. Several application domains can exist in a single process, and the thread can span the application domain, a method in a thread can call a method in another thread, so that it does not cause additional overhead for inter-process calls or inter-process switching. It can be said that the application domain is a logical Process within the physical Process (that is, the Process in win32.
In objective l c #, The System. Threading namespace provides classes and interfaces that allow multi-threaded programming. The following three methods are available for Thread creation: Thread, ThreadPool, and Timer. Next I will give a brief introduction to their usage methods one by one.
1. Thread
This may be the most complicated method, but it provides various flexible control over the thread. First, you must use its constructor to create a thread instance. Its parameters are relatively simple and there is only one ThreadStart delegate:
[C #]
Public Thread (ThreadStart start );
Call Start () to Start it. Of course, you can use its Priority attribute to set or obtain its running Priority (enum ThreadPriority: Normal, Lowest, Highest, BelowNormal, AboveNormal ). See the following example: it first generates two thread instances t1 and t2, then sets their priorities respectively, and then starts two threads (the two threads are basically the same, but their output is different, t1 is "1" and t2 is "2". The ratio of their respective output characters to the CPU usage time is roughly displayed, which also reflects their respective priorities ).
Static void Main (string [] args)
{
Thread t1 = new Thread (new ThreadStart (Thread1 ));
Thread t2 = new Thread (new ThreadStart (Thread2 ));


T1.Priority = ThreadPriority. BelowNormal;
T2.Priority = ThreadPriority. Lowest;
T1.Start ();
T2.Start ();
}
Public static void Thread1 ()
{
For (int I = 1; I <1000; I ++)
{// Write a "1" for each running Loop"
Dosomething ();
Console. Write ("1 ");
}
}
Public static void Thread2 ()
{
For (int I = 0; I <1000; I ++)
{// Write a "2" for each running Loop"
Dosomething ();
Console. Write ("2 ");
}
}
Public static void dosomething ()
{// Used to simulate complex operations
For (int j = 0; j <10000000; j ++)
{
Int a = 15;
A = a *;
}
}
The program running result is as follows:


11111111111111111111111111111111111111111121111111111111111111111111111111111111111112


11111111111111111111111111111111111111111121111111111111111111111111111111111111111112


11111111111111111111111111111111111111111121111111111111111111111111111111111111111112

From the above results, we can see that t1 threads occupy much more CPU time than t2, because t1 has a higher priority than t2, if we set the priority of t1 and t2 to Normal, what is the result? Will they take the same CPU time? Yes, as expected, see:


121211221212121212121212121212121212121212121212121212121212121212121


212121212121212121212121212121212121212121212121212121212121212121212


121212121212121212



From the above example, we can see that its construction is similar to that of win32 worker threads, but it is simpler to use the function to be called by the thread as the delegate and then the delegate as the parameter to construct the thread instance. After Start () is called, the corresponding function is called and executed from the first line of the function.
Next, we will learn about thread control based on the ThreadState attribute of the thread. ThreadState is an enumeration type that reflects the state of a thread. When a Thread instance is just created, its ThreadState is Unstarted; when the Thread is started by calling Start (), its ThreadState is Running; after the Thread is started, if you want to suspend (Block) It, You can call Thread. sleep () method, which has two overload methods (Sleep (int) and Sleep (Timespan), except that the format of time is different, when this function is called in a thread, it indicates that the thread will be blocked for a period of time (the time is determined by the number of milliseconds passed to Sleep or Timespan, if the parameter is set to 0, the thread is suspended for execution by other threads, and Infinite is specified to block the thread indefinitely. In this case, the ThreadState of the thread changes to WaitSleepJoin, in addition, it is worth noting that the Sleep () function is defined as static ?! This also means that it cannot be used together with a thread instance, that is, there is no call similar to t1.Sleep (10! In this case, the Sleep () function can only be called by the thread that needs to "Sleep" and cannot be called by other threads. Just as the reason why to Sleep is a private matter, it cannot be decided by others. However, when a Thread is in the WaitSleepJoin state and has to wake up, you can use the Thread. the Interrupt method will trigger ThreadInterruptedException on the thread. Let's take a look at an example (pay attention to the Sleep call method ):
Static void Main (string [] args)
{
Thread t1 = new Thread (new ThreadStart (Thread1 ));
T1.Start ();
T1.Interrupt ();
E. WaitOne ();
T1.Interrupt ();
T1.Join ();
Console. WriteLine ("t1 is end ");
}
Static AutoResetEvent E = new AutoResetEvent (false );
Public static void Thread1 ()
{
Try
{// It can be seen from the parameter that it will cause sleep
Thread. Sleep (Timeout. Infinite );
}
Catch (System. Threading. ThreadInterruptedException e)
{// Interrupt handler
Console. WriteLine ("1st interrupt ");
}
E. Set ();
Try
{// Sleep
Thread. Sleep (Timeout. Infinite );
}
Catch (System. Threading. ThreadInterruptedException e)
{
Console. WriteLine ("2nd interrupt ");
} // Pause for 10 seconds
Thread. Sleep (10000 );
}
Running result: 1st interrupt
2nd interrupt
(10 s later) t1 is end
We can see from the above example that Thread. the Interrupt method can wake the program from a blocking (WaitSleepJoin) state to the corresponding Interrupt Processing Program, and then continue to execute (its ThreadState also changes to Running ), note the following when using this function:
1. This method can not only wake up the blocking caused by Sleep, but also be effective for all methods (such as Wait and Join) that can cause the thread to enter the WaitSleepJoin state. As shown in the preceding example, the method that causes thread blocking should be put into the try block, and the corresponding interrupt handler should be put into the catch Block.
2. interrupt is called for a thread. If it is in the WaitSleepJoin state, it enters the corresponding Interrupt processing program execution. If it is not in the WaitSleepJoin State, when it enters this state, will be immediately interrupted. If Interrupt is called several times before the interruption, only the first call is valid. This is the reason why I used synchronization in the previous example. In this way, the second call to Interrupt is called after the first disconnection, otherwise, the second call may be invalid (if it is called before the first interruption ). You can try to remove synchronization. The result is probably 1st interrupt.
In the preceding example, two other methods are used to bring the Thread into the WaitSleepJoin state: the synchronization object and the Thread. Join method. The Join method is easy to use. It indicates that the current thread that calls this method is blocked until another thread (t1 in this example) when either of the two conditions (if any) appears, it immediately ends WaitSleepJoin and enters the Running state (according. the Return Value of the Join method determines the condition. If it is true, the thread is terminated. If it is false, the time is reached ).
Thread suspension is also available. suspend method. When a thread is in the Running state, it calls the Suspend method. It enters the SuspendRequested state, but it is not immediately suspended, the thread can be Suspended until it reaches the security point. At this time, the thread enters the sucanceled ded state. For example, a Thread that is already in the susponded state is invalid. to Resume the operation, you only need to call Thread. Resume.
Finally, we talk about thread destruction. We can call the Abort method for the thread to be destroyed, which will cause ThreadAbortException on this thread. We can put some code in the thread into the try block and put the corresponding processing code into the catch Block. When the thread is executing the code in the try block, if it is called Abort, it will jump into the corresponding catch block for execution, and it will terminate after the code within the catch fast (if the catch Block executes ResetAbort, it will be different: it will cancel the current Abort request and continue to execute. Therefore, to ensure that a thread is terminated, it is best to use Join, as shown in the preceding example ).






2. ThreadPool
ThreadPool is a relatively simple method. It is suitable for some short tasks that require multiple threads (such as some threads that are often blocked ), its disadvantage is that it cannot control the created thread or set its priority. Since each process has only one thread pool, and of course each application domain has only one thread pool (line-to-line), you will find that all the member functions of the ThreadPool class are static! When you call ThreadPool. QueueUserWorkItem and ThreadPool. RegisterWaitForSingleObject for the first time, a thread pool instance will be created. Next I will introduce the two functions in the thread pool:
[C #]
Public static bool QueueUserWorkItem (// if the call is successful, true is returned.
WaitCallback callBack, // Delegate of the thread call to be created
Object state // parameters passed to the Delegate
) // Another overload function is similar, but the delegate does not contain parameters.
This function queues the threads to be created to the thread pool. When the number of available threads in the thread pool is not zero (the thread pool has a limit on the number of threads to be created, if the value is 25, the thread is created. Otherwise, the thread is queued to the thread pool until it has available threads.
[C #]
Public static RegisteredWaitHandle RegisterWai

Related Article

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.