问题:当同步操作复杂,或调用外部没有异步方法,阻塞主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