hello, see you again. Through the introduction of the previous two articles, you have a good understanding and use of task creation, operation, blocking, synchronization, continuation, etc. Combined with the actual scenario, this can also solve a large part of the multi-threaded business in the actual work, but only these are far from enough, such asIn such a scenario, when a tsak asynchronous task is turned on and a conditional trigger occurs, how can the execution of the tsak be terminated?These are just the parts we need to share today. With these questions, let's get to today's topic together. Thank you.

If you haven't read the previous two articles before you enter the topic, you are welcome to click on the address below to read them first, so that you can have a more consistent understanding of today's content. Thank you!

First: Talk about one of the multi-threaded task s creating runs and blockages

Second: Talk about what's multi-threaded and what's the second task continuation

 

Task's Task Cancellation: CancellationTokenSource

 

With regard to thread cancellation, I believe you will encounter such problems in your practice that no matter which way you implement asynchronous threads, you will have the appropriate mechanisms to cancel thread operations.Thread's thread cancellations will also be implemented this time, and Tsak's thread cancellations will be illustrated by an example.

In my work experience, the actual scenarios where asynchronous threaded jobs need to be cancelled are often asynchronous job programs, which are periodic, circular business operations.Such as periodic data synchronization, data updates, and so on.For example: a common scenario in e-commerce systems, order timeout cancellation, and so on.

In order to be consistent with the previous two examples, I would like to take the data synchronization business on the hotel platform as an example:

Requirements: Fully synchronize the latest hotel data every Wednesday at 3 am through the hotel paging query interface provided by Ctrip.It can also terminate data synchronization operations through human intervention.

* Here I'll do it through Thread and Tak, respectively

1. Task cancellation in the Thread Era

* Ha-ha, to be honest, I also used Thread to implement asynchronous threads in projects a few years ago, and I also encountered a business scenario where threads cancelled.I did this by defining a global variable, isStopThread (whether or not to terminate the thread), and by going over tasks that need to be cancelled, I just need to control the value of isStopThread. Each time I perform a specific business, I first judge isStopThread, and only the non-terminating state executes the specific business logic.

 /// <summary>
 /// Ctrip Hotel Data Synchronization Job(Thread)
 /// </summary>
 private static void CtripHoteDataSynchrByThread()
 {
     CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
     // Step 1 Pass thread Open a thread
     Thread thread = new Thread(() =>
     {
         // Number of times to get data
         int getDataIndex = 1;
         isStopCtripHoteDataSynchr = false;

         // Get valid hotel data by calling Ctrip's paging service
         // Before you get the data, first decide whether to terminate the fetch

         while (!cancellationTokenSource.IsCancellationRequested)
         {
             // Now let's assume a simulation that captures all the valid hotel data for Ctrip in three passes
             Console.WriteLine($"Start acquiring Ctrip {getDataIndex} Page Hotel Data....\n");

             Thread.Sleep(3000);
             Console.WriteLine($"Ctrip {getDataIndex} Page Hotel Data Obtained\n");
             getDataIndex++;

             // Simulate the completion of the third page of data acquisition, representing the completion of data acquisition, directly terminate
             if (getDataIndex == 4)
             {
                 Console.WriteLine($"Synchronize all hotel data of Ctrip\n");
                 break;
             }
         }

         if (isStopCtripHoteDataSynchr)
         {
             Console.WriteLine($"Cancel Synchronizing Ctrip Hotel Data\n");
         }
     });

     thread.Start();

     Console.WriteLine("Ctrip Hotel Data Synchronization.....\n");
     // Simulate cancellations in actual data synchronization
     Console.WriteLine("If you need to unsynchronize the data, type any character to cancel the operation\n");

     Console.ReadLine();

     cancellationTokenSource.Cancel();
     isStopCtripHoteDataSynchr = true;

     Console.WriteLine($"Initiate a request to cancel synchronization of Ctrip hotel data\n");
 }

Execution results:

From the test results, we can see that when we get the data on page 2, a cancel thread command is launched, and when the data on page 2 is obtained, the thread terminates inside, thus reaching the goal of thread cancelling.

Second, Task Era Task Cancellation

With the introduction of Task, Microsoft has also introduced a CancellationTokenSource which is designed to help us cancel a thread. To say nothing, let's start with the CancellationTokenSource class.

/// <summary>
 /// Ctrip Hotel Data Synchronization Job(Task)
 /// </summary>
 private static void CtripHoteDataSynchrByTask()
 {
     // Define a task cancellation mechanism
     CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

     // Step 1 Pass thread Open a thread
     Task thread = new Task(() =>
     {
         // Number of times to get data
         int getDataIndex = 1;

         // Get valid hotel data by calling Ctrip's paging service
         // Before you get the data, first decide whether to terminate the fetch

         while (!cancellationTokenSource.IsCancellationRequested)
         {
             // Now let's assume a simulation that captures all the valid hotel data for Ctrip in three passes
             Console.WriteLine($"Start acquiring Ctrip {getDataIndex} Page Hotel Data....\n");

             Console.WriteLine($"Ctrip {getDataIndex} Page Hotel Data Obtained\n");
             getDataIndex++;

             // Simulate the completion of the third page of data acquisition, representing the completion of data acquisition, directly terminate
             if (getDataIndex == 4)
             {
                 Console.WriteLine($"Synchronize all hotel data of Ctrip\n");
                 break;
             }
         }

         if (cancellationTokenSource.IsCancellationRequested)
         {
             Console.WriteLine($"Cancel Synchronizing Ctrip Hotel Data\n");
         }
     });
     thread.Start();

     Console.WriteLine("Ctrip Hotel Data Synchronization.....\n");
     // Simulate cancellations in actual data synchronization
     Console.WriteLine("If you need to unsynchronize the data, type any character to cancel the operation\n");

     Console.ReadLine();

     // Direct Thread Cancellation
     cancellationTokenSource.Cancel();

     // Cancel thread after specified time
     // cancellationTokenSource.CancelAfter(1000);

     Console.WriteLine($"Initiate a request to cancel synchronization of Ctrip hotel data\n");
 }
 

Test results:

 

The results of both implementations are identical through the test

Of course, CancellationTokenSource also provides a CancelAfter method for how long to cancel threads.

When it comes to this, I don't know if you find a problem whether CancellationTokenSource's implementation has little to do with Task and Thread. Thread cancellations in the first instance can also be done in conjunction with CancellationTokenSource.That's why, at the beginning, I said CancellationTokenSource was a help class provided by Microsoft for thread cancellation.In fact, I can open the implementation source of CancellationTokenSource, which we will see at a glance. The core logic of Thread cancellation is similar to what we said above, that is, to control the value of a variable, but CancellationTokenSource encapsulates all its operations.Inside CancelAfter, a definitor is opened, and the final implementation of the timer is the same as that of CancelAfter.If you want to see the source code for CancellationTokenSource, you can check the following address: https://www.cnblogs.com/majiang/p/7920102.html

Finally, it should be noted that both Task and Cancellation TokenSource are.Net Framework 4.0+,.NET Core,.NET Standard.

 

Asynchronous methods: (async/await)

 

Microsoft c#5.0 has introduced a new feature, Asynchronous Method, with the keyword async.With async, it's much easier to implement an asynchronous method, and you'll find that it's very similar to implementing a synchronous method, just by modifying the method with async.Of course, if it's just a simple decorative call, it's also synchronous. To make a real asynchronous call, you often need another keyword, await, to work with it.

Start with a brief introduction to async asynchronous functions:

Three return types for async:

Tsak: The main scenario for this is that the main program only cares about the state of asynchronous method execution and does not need to interact with any execution result data from the main thread.

Task<T>: The main scenario for this is that the main program is not only concerned with the state of asynchronous method execution, but also wants to return a result with a data type of T after execution.

Void: The main program does not care about the state of asynchronous method execution or the result of its execution, but calls the asynchronous method once. For code other than event handlers, the async void method is generally not encouraged because the caller cannot

In introducing await keywords:

Wait, as its name implies, means wait. It works by the principle that when the caller executes await, it returns immediately, but asynchronous methods wait for the result of asynchronous execution.So await can only exist in the async-decorated asynchronous method body. Instead of blocking the main thread, it can only block the current asynchronous method from executing further, so that the real asynchronous purpose can be achieved.

Here is a simple example to illustrate the use of each case:

static void Main(string[] args)
 {
     Console.WriteLine("Main Thread Start\n");
     Console.WriteLine("The main thread calls the synchronization method: SynTest\n");
     SynTest();

     Console.WriteLine("The main thread calls the asynchronous method: AsyncTestNoAwait\n");
     AsyncTestNoAwait();

     Console.WriteLine("The main thread calls the asynchronous method: AsyncTestHasAwait\n");
     AsyncTestHasAwait();

     Console.WriteLine("End of Main Thread\n");
     Console.ReadKey();
 }

 /// <summary>
 /// Synchronization Method Test
 /// </summary>
 public static void SynTest()
 {
     Console.WriteLine("Synchronization method SynTest Start running\n");
     Thread.Sleep(5000);
     Console.WriteLine("Synchronization method SynTest End of run\n");
 }

 /// <summary>
 /// Asynchronous Method Test (without await Keyword)
 /// </summary>
 public static async void AsyncTestNoAwait()
 {
     Console.WriteLine("Asynchronous Method AsyncTestNoAwait Start running\n");
     Thread.Sleep(5000);
     Console.WriteLine("Asynchronous Method AsyncTestNoAwait End of run\n");
 }

 /// <summary>
 /// Asynchronous Method Test (with await Keyword)
 /// </summary>
 public static async void AsyncTestHasAwait()
 {
     Console.WriteLine("Asynchronous Method AsyncTestHasAwait Start running\n");
     await Task.Delay(5000);
     Console.WriteLine("Asynchronous Method AsyncTestHasAwait End of run\n");
 }

Run result:

From the results we can see very well:

1. If asynchronous method async has no await keyword, how it works or is called synchronously

2. The await keyword can only exist in the cloud async modified method body

3. When async method is called, only the block after await keyword is executed asynchronously, and the block before await keyword is executed synchronously

Well, management async is introduced here first. Due to the time and length of the article, it is not detailed. There is still a lot to be noticed, and a special article on async/await will follow.

Summary:

This concludes all three articles on Task so far. Here's a review of Task's features.

1. Task can be created and run in three ways: new Task/Task.Factory/Task.Run

2. Task's return parameters define Task<return type>

Get the return value: Task.Result->Block the main process

3. The synchronization of Task threads can be achieved not only by RunSynchronously, but also by Task.Result/Task.Wait, etc.

4. Task's wait/waitAll/waitAny implementation blocks waiting for execution results

5. WhenAny, WhenAll, ContinueWith of Task for continuation operation

6. CancellationTokenSource Implements Asynchronous Task Cancellation

7. Asynchronous methods: (async/await) synchronous and asynchronous calls, etc.

 

Guess you like:

First: Talk about one of the multi-threaded task s creating runs and blockages

Article 2: Talk about what's multi-threaded and what's the second task continuation

END
For higher communication, please pay attention to my public number. Scan the following two-dimensional code to pay attention. Thank you: