How to cancel execution of. net background threads

Source: Internet
Author: User

Introduction
When using multi-threaded models for programming, one of the common problems is that when we close the front-end UI thread, the background auxiliary thread is still active, as a result, the entire application cannot exit normally. At this time, we need a safer way to end the running of background threads, so that we can end the running of background threads at any time, at the end of the thread, clear the corresponding resources (for example, write the memory data to the hard disk ).. Net Framework provides some tools to implement this function.

Directory
IsBackground attributes
Abort Method
Round Robin Mode
Cancel the blocked thread
IsBackgound attributes
The Thread class provides the IsBackground attribute. When the IsBackground attribute of a Thread is set to true, this Thread is a background working Thread. When an application ends, all its background threads are automatically executed. If you have a background thread that listens for Socket connections and is being blocked, set the IsBackground attribute of the thread to True at this time, it is more appropriate to make it automatically end with the end of the application. But in this case, the thread will quietly end, it will not cause any exceptions, your thread has no chance to execute some of the necessary cleaning code. For example, data in the memory may be too late to be written to the disk, resulting in data loss.

Abort Method
You can call the Abort method of the Thread class to force the final Thread. When this method is called on, ThreadAbortException is triggered on the thread and is redirected to the end of the thread. By capturing this exception, some resource cleanup code can be executed. However, this mode also has some problems, mainly because it is difficult to know where the code on the thread is executed, and it is difficult to compile all the corresponding resource cleanup code. In general, this is a rough method to terminate thread execution, which is generally not recommended.

Round Robin Mode
If the background thread will execute a long calculation, the calculation can be divided into several small sections, and it is often checked whether to cancel the thread .. NET Framework provides the CancellationTokenSource class as the unified mode for thread cancellation. For example:Copy codeThe Code is as follows: public class Example
{
Public static void Main ()
{
CancellationTokenSource cts = new CancellationTokenSource ();
Var thread = new Thread (ThreadWork );
Thread. Start (cts. Token );
While (true)
{
If (Console. ReadKey (). KeyChar = 'C ')
{
Console. WriteLine ("request cancellation thread execution ");
Cts. Cancel ();
Break;
}
}
Console. ReadLine ();
}

Private static void ThreadWork (object state)
{
CancellationToken cancellationToken = (CancellationToken) state;

While (true)
{
// Check whether the task is canceled
If (cancellationToken. IsCancellationRequested)
{
Console. WriteLine ("the thread has been canceled ");
Console. WriteLine ("the thread resources have been cleared. ");
Break;
}
// Simulate the work
Thread. SpinWait (500000 );
Console. WriteLine ("I am still working. ");
}
}
}

Cancel the blocked thread
In the above example, the background thread will perform computing for a long time, but more often, the thread will enter the blocking state due to waiting for an event. At this time, the thread is no longer in the execution status. Obviously, it has no chance to check the cancellation mark. So how can we solve this problem? The WaitHandle attribute of CancellationToken provides answers. The WaitHandle class has a static method WaitAny, which can wait for multiple events at the same time. When any of the multiple events is valid, the thread will return from the blocking state. You can determine the event based on the return value of the WaitAny method and execute the Code accordingly. Example:Copy codeThe Code is as follows: public class Example
{
Private static int Value;

Public static void Main ()
{
Var autoResetEvent = new AutoResetEvent (false );
Var cts = new CancellationTokenSource ();
Var state = new {ValueAvailableEvent = autoResetEvent, CancellationToken = cts. Token };
Var threadConsumer = new Thread (ConsumerThreadWork );
Var threadProducter = new Thread (ProducterThreadWork );

ThreadConsumer. Start (state );
ThreadProducter. Start (state );

While (true)
{
If (Console. ReadKey (). KeyChar = 'C ')
{
Console. WriteLine ("request cancellation thread execution ");
Cts. Cancel ();
Break;
}
}
Console. ReadLine ();

}
Public static void ProducterThreadWork (dynamic state)
{
Var valueAvailableEvent = (AutoResetEvent) state. ValueAvailableEvent;
Var cancellationToken = (CancellationToken) state. CancellationToken;
Var rand = new Random ();
While (! CancellationToken. IsCancellationRequested)
{
Value = rand. Next ();
Console. WriteLine ("\ r \ n generates a Value {0}", Value );
ValueAvailableEvent. Set ();
Thread. Sleep (500 );
}

Console. WriteLine ("the producer thread is canceled. ");
}

Public static void ConsumerThreadWork (dynamic state)
{
Var valueAvailableEvent = (AutoResetEvent) state. ValueAvailableEvent;
Var cancellationToken = (CancellationToken) state. CancellationToken;
Var events = new [] {valueAvailableEvent, cancellationToken. WaitHandle };

While (true)
{
Var eventIndex = WaitHandle. WaitAny (events );
// Process data
If (eventIndex = 0)
{
Console. WriteLine ("processing value {0 }. ", Value );
}
// Handle the cancellation event
Else if (eventIndex = 1)
{
Console. WriteLine ("the consumer thread is canceled. ");
Break;
}
}
}
}

In the preceding example, there are three threads: UI thread, producer thread, and consumer thread. The producer thread generates a valid Value every second and saves the data to the Value field. The consumer thread waits for the Value to be generated, which is blocked. All consumption threads use WaitHandle. the WaitAny method is used to wait for a value-effective event or cancel the event. When any event is valid, the thread continues, and the returned value is used to judge and process the event.

Summary
The thread cancellation problem in the multithreading model is still complicated. The Thread. IsBackground attribute provides a method to automatically end a Thread after the foreground Thread ends. The Thread. Abort method provides a method to end a Thread in a "crude" way. The CancellationTokenSource class is the standard mode for thread cancellation. We should use this mode more. There are not many articles written, basically because the number of words is not enough. Let's just look at the code.

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.