C# 将同步操作或方法变成异步

102 阅读1分钟

问题:当同步操作复杂,或调用外部没有异步方法,阻塞主UI线程怎么办?

解决:使用Task.Run()将同步操作嵌套。再使用CancellationToken 来停止异步任务。

//无返回值
public async Task FunAsync(CancellationToken? CTtoken=null)  
 {
     var token = CTtoken ?? CancellationToken.None;
     Task.Run(()=>{ 
         token.ThrowIfCancellationRequested(); //抛出异常结束异步任务
         while(true);
     });
 }
//有返回值
public async Task<bool> FunAsync(CancellationToken? CTtoken=null)  
 {
     var token = CTtoken ?? CancellationToken.None;
     Task.Run(()=>{ 
         //token.ThrowIfCancellationRequested(); 
         while(true);
     },token);      //或者可以将token放在Run重载方法的第二个参数上。
 }
//调用
try{
    CancellationTokenSource CTSource = new CancellationTokenSource();
    await FunAsync(CTSource.Token);//无返回值
    // bool result = awaitFunAsync(CTSource.Token) //有返回值
}
catch(OperationCanceledException)
{
    //任务被取消
}
//取消
 CTSource.Cancel(); //取消任务

当执行了Cancel()后,想重新启动异步任务,需要重新实例化CancellationTokenSource,

CTSource = new CancellationTokenSource();

当Task.Run里有异步方法时,需要给第一个委托参数加上async关键字,且token可以放在异步方法(要是异步方法可以接受token参数)参数里,如

public async Task FunAsync(CancellationToken? CTtoken=null)  
 {
     var token = CTtoken ?? CancellationToken.None;
     Task.Run(async()=>{ 
         //token.ThrowIfCancellationRequested(); //抛出异常结束异步任务
         while(true){
             await Task.Delay(50,token);
         }
     });
 }

参考链接:

https://www.bilibili.com/video/BV1Cw411A7Fr