Detailed explanation of C# Task tasks

Preface

Task is an encapsulation of Thread. It is an extremely optimized design, which makes it more convenient for us to control threads.

Task

Task declaration looks like:

public static  Task Sleep()
{
    
    

}

Task is a type

return value

Directly declaring Task requires a return value.
Insert image description here

Return without parameters

public static  Task Sleep(int second)
{
    
    
    
    return Task.CompletedTask;
}

Return with parameters

 public static  Task<T> Sleep()
 {
    
    
     return Task.FromResult(T);
 }
//举例,返回参数只能唯一,除非使用元祖
 public static  Task<string> Sleep()
 {
    
    
     return Task.FromResult("Hello world!");
 }

Use Task.Result to get the return value


var res = Sleep().Result;

async and await

async and await are controls for asynchronous events, making it easier for us to control asynchronous events.

return value

You can set the return value directly after using async

///有参返回
 public static async  Task<string> Sleep()
 {
    
    

     return "Hello world";
 }
 ///无参返回
  public static async  Task Sleep()
 {
    
    
 }

Use with await

Waiting for asynchronous events uses the await method

        public static async Task Sleep(int second)
        {
    
    
            await Task.Delay(second * 1000);

            Console.WriteLine($"等待{
      
      second}s");
        }
        static void Main(string[] args)
        {
    
    
            Sleep(3);
            Sleep(2);
            Sleep(1);
            Console.WriteLine("运行完毕");
            //使用键盘键入事件阻塞主进程,主进程结束程序会立即退出
            Console.ReadKey();

        }

Print the result:
Insert image description here

The print result shows:

  • The synchronization event ends first
  • Asynchronous events do not block each other, 3, 2, 1 start at the same time, wait for 3, 2, 1s to print 1, 2, 3.

Main async transformation

The main program is Void and cannot wait.

Insert image description here
Change Void to Task to wait for asynchronous events.
Insert image description here
Print the result service expectations and wait for the asynchronous events to end before running.
Insert image description here

Task advanced

C#Task Cancel Task Execution CancellationTokenSource
C# Task Pause and Cancel

Task thread canceled

Thread used to have the Abort() method to forcibly destroy the thread, but this method was used for great security issues and has been deprecated.

Insert image description here
Threads cannot be destroyed directly, they can only be canceled by throwing an exception.

//声明token
var tokenSource = new CancellationTokenSource();
//注册异常抛出
tokenSource.Token.ThrowIfCancellationRequested();
//注册取消事件回调
tokenSource.Token.Register(() =>
{
    
    
    Console.WriteLine("线程已被取消");
});



。。。。。。别的地方的代码
//取消token,那么之前写ThrowIfCancellationRequested的地方会直接结束
tokenSource.Cancel();

test case

A simple infinite loop function that returns token during runtime and is used to jump out of the program directly.

static async Task Main(string[] args)
{
    
    

    var token = Loop();
    //等待3s抛出异常
    await Task.Delay(1000 * 3);
    Console.WriteLine("任务完成!");

    token.Cancel();
    Console.ReadKey();

}

/// <summary>
/// 循环等待
/// </summary>
/// <returns></returns>
public static CancellationTokenSource Loop()
{
    
    
    var tokenSource = new CancellationTokenSource();
    Console.WriteLine("任务开始!");
    tokenSource.Token.Register(() =>
    {
    
    
        Console.WriteLine("线程已被取消");
    });
    var count = 0;
    Task.Run(async () =>
    {
    
    
        while (true)
        {
    
    
           await Task.Delay(1000);
           //抛出异常,直接结束线程
            tokenSource.Token.ThrowIfCancellationRequested();
            count++;
            Console.WriteLine(count);
        }
    });
    return tokenSource;
}

Print results

Insert image description here

It is also safer to use.

Timeout settings

tokenSource.CancelAfter is a timeout method.
CancelAfter(1000): Timeout after 1000 milliseconds

 static async Task Main(string[] args)
 {
    
    
     var token = Loop();
     ///3000毫秒后取消
     token.CancelAfter(1000*3);
     Console.ReadKey();

 }


 /// <summary>
 /// 循环等待
 /// </summary>
 /// <returns></returns>
 public static CancellationTokenSource Loop()
 {
    
    
     var tokenSource = new CancellationTokenSource();
     Console.WriteLine("任务开始!");
     tokenSource.Token.Register(() =>
     {
    
    
         Console.WriteLine("线程已被取消");
     });
     var count = 0;
     Task.Run(async () =>
     {
    
    
         while (true)
         {
    
    
             await Task.Delay(1000);
             tokenSource.Token.ThrowIfCancellationRequested();
             count++;
             Console.WriteLine(count);
         }
     });
     return tokenSource;
 }

Thread pause and resume

Thread suspension is also controlled using a class, ManualResetEvent. Just like thread destruction, it cannot be paused directly, because it is not safe to pause directly.

//声明,false为默认阻塞,true为不阻塞
var resetEvent = new ManualResetEvent(false);
//暂停,通过WaitOne方法来阻塞线程,通过Set和Reset来设置是否阻塞
resetEvent.WaitOne();
//阻塞暂停
resetEvent.Set()
//取消阻塞,继续
resetEvent.Reset()

test case
  static async Task Main(string[] args)
  {
    
    

      var canStop = CanStop();
      //等待3s抛出异常
      Console.WriteLine("等待3s启动");
      await Task.Delay(1000 * 3);
      Console.WriteLine("启动!");
      canStop.Set();
      
      Console.WriteLine("等待3s暂停");
      await Task.Delay(3000);
      Console.WriteLine("暂停!");
      canStop.Reset();

      Console.ReadKey();

  }
   public static ManualResetEvent CanStop()
 {
    
    
     var resetEvent = new ManualResetEvent(false);
     var count = 0;
     Task.Run(async () =>
     {
    
    
         while (true)
         {
    
    
             resetEvent.WaitOne();
             await Task.Delay(1000);
             
             count++;
             Console.WriteLine(count);
         }
     });
     return resetEvent;

 }

Multitasking is the fastest

await Task.WhenAny(Task1,Task2,Task3)
will only wait for the fastest one.

        static async Task Main(string[] args)
        {
    
    
            await Task.WhenAny(Sleep(1),Sleep(2),Sleep(3));
            
            Console.WriteLine("运行结束");
            Console.ReadKey();

        }

        public async static Task Sleep(int second)
        {
    
    
            await Task.Delay(second*1000);

            Console.WriteLine($"等待{
      
      second}s");
        }

operation result

Insert image description here

Multitasking all waiting

        static async Task Main(string[] args)
        {
    
    
            await Task.WhenAll(Sleep(1), Sleep(2), Sleep(3));

            Console.WriteLine("运行结束");
            Console.ReadKey();

        }

        public async static Task Sleep(int second)
        {
    
    
            await Task.Delay(second*1000);

            Console.WriteLine($"等待{
      
      second}s");
        }

Insert image description here

in conclusion

The control of asynchronous threads is extremely important. Tasks can also be used together with delegates to have stronger control over the running of the program.

Guess you like

Origin blog.csdn.net/qq_44695769/article/details/133382380