链接:http://www.cnblogs.com/mi12205599/p/10572840.html
在中运行异步代码。NET和C#相当简单,因为我们有时候需要取消正在进行的异步操作。通过这篇文章,我们可以知道如何通过CancellationToken取消任务(包括不可取消的任务)。
早期
在早期,。NET使用BackgroundWorker完成异步长时间运行的操作。
您可以使用CacnelAsync方法设置CancellationPending = true
private void backgroundlongruningtask(object sender,DoWorkEventArgs e)
{
background Worker =(background Worker)发件人;
for(inti = 1;i <。= 10000;i++)
{
if(工人。CancellationPending = = true)
{
e.Cancel = true
打破;
}
//做点什么
}
}
对于异步和长时间运行的操作,不再推荐使用这种方法,但是大多数概念今天仍然可以使用。
任务横空诞生了
任务表示异步操作,此类表示不返回值的异步操作。通用版本任务
Async/await语法糖码可以用来完成异步操作。
下面创建一个简单的长时间运行的操作:
///<。摘要>。
///长时间计算一个值。
///<。/summary>。
///<。退货>。计算出的值。& lt/returns>。
///<。param name="loop ">。要进行的迭代次数。& lt/param>。
私有静态任务<。十进制>LongRunningOperation(intloop)
{
//启动任务并返回
returnTask。运行(()= >;
{
抽取结果= 0;
//循环定义的迭代次数
for(inti = 0;i <。循环;i++)
{
//做一些需要时间的事情,比如线程。睡懒觉。NET Core 2。
线程。睡眠(10);
结果+= I;
}
returnresult
});
}
//这里我们使用Thread。睡眠模拟长时间运行的操作
简单异步调用代码:
publicationstatisycontask ExecuteTaskAsync()
{
控制台。WriteLine(名称为(ExecuteTaskAsync));
控制台。WriteLine("结果{0} ",awaitLongRunningOperation(100));
控制台。写线(“按回车键继续”);
控制台。ReadLine();
}敲黑板:C#取消异步操作如下
(1)让代码可以被取消(可取消)
由于某些原因,长时间运行的操作需要很长时间(需要取消以避免占用资源);或者不想等待执行结果,我们就取消异步操作。
取消令牌需要在长期运行的异步任务中传递,以便完成:
///<。摘要>。
///长时间计算一个值。
///<。/summary>。
///<。退货>。计算出的值。& lt/returns>。
///<。param name="loop ">。要进行的迭代次数。& lt/param>。
///<。param name = " cancellationToken " >取消令牌。& lt/param>。
私有静态任务<。十进制>longrunning cancelallableoperation(int loop,cancelationtoken cancelationtoken)
{
任务<。十进制>task = null
//启动任务并返回
任务=任务。运行(()= >;
{
抽取结果= 0;
//循环定义的迭代次数
for(inti = 0;i <。循环;i++)
{
//检查是否请求取消,如果是,
//引发TaskCanceledException。
if(CancelationToken。IsCancellationRequested)
thrownewTaskCanceledException(任务);
//做一些需要时间的事情,比如线程。睡懒觉。NET Core 2。
线程。睡眠(10);
结果+= I;
}
returnresult
});
returntask
}
在长时间运行的操作中,我监视IsCancellationRequested方法(取消命令目前是否出现)。在这里,我倾向于包装一个TaskCanceledException异常类(给上层方法的调用者更多的处理可能性);当然可以调用ThrowIfCancellationRequested方法抛出OperationCanceledException异常。
②触发取消命令
CancellationToken结构相当于在异步操作内部打入楔子,随时等待后面发送的取消命令。
操纵上述取消令牌状态的对象是取消令牌源,它是取消操作的命令发布者。
默认构造函数支持超时取消:
//下面的代码使用CancellationSource默认构造函数来完成超时取消
publicationstatisycontask ExecuteTaskWithTimeOutAsync(时间跨度时间跨度)
{
控制台。WriteLine(名称为(ExecuteTaskWithTimeOutAsync));
使用(varcancelationtokensource = new cancelationtokensource(timeSpan))
{
尝试
{
var result = awaitlongrunning cancelableoperation(500,cancellationTokenSource。令牌);
控制台。WriteLine( "Result {0} ",Result);
}
捕获(任务取消异常)
{
控制台。写线(“任务已取消”);
}
}
控制台。写线(“按回车键继续”);
控制台。ReadLine();
}
附件①:高级操作,完全手动取消:
自然,我们注意到了CancellationSource的几种方法。如果我们想在异步操作时手动取消操作,我们需要建立另一个线程来等待手动取消操作的指令。
publicationstatisycontask execute manuallycancelabletaskasync()
{
控制台。WriteLine(名称为(ExecuteManualLycancelableTaskAsync));
使用(VarCancelationTokenSource = NewCancelationTokenSource())
{
//创建一个听键盘按键的任务
变量键盘任务=任务。运行(()= >;
{
控制台。写线(“按回车键取消”);
控制台。read key();
//取消任务
取消令牌源。cancel();
});
尝试
{
varlongrunning task = longrunning cancelableoperation(500,cancellationTokenSource。令牌);
var result = awaitlongrunning Task;
控制台。WriteLine( "Result {0} ",Result);
控制台。写线(“按回车键继续”);
}
捕获(任务取消异常)
{
控制台。写线(“任务已取消”);
}
awaitkeyBoardTask
}
}
//以上是异步接收控制台输入并发出取消命令的控制台程序。
附件②:高级操作,取消不可取消任务:
有时,异步操作代码不支持取消,即上述长时间运行的异步操作
Longrunningcancelable操作(int loop,cancellation token cancellation)不提供参数2,这相当于不允许楔形驱动。
这个时候,如何才能取消这样一个不可取消的任务?
您可以考虑使用任务。当任何(参数任务)操作曲线取消时:
利用TaskCompletionSource 注册异步可取消任务等待待non-cancellable 操作和以上建立的 异步取消操作privatestaticasyncTask<decimal> LongRunningOperationWithCancellationTokenAsync(intloop, CancellationToken cancellationToken){
//我们创建一个十进制的任务完成源
var TaskCompletionSource = NewTaskCompletionSource & lt;十进制>();
//将lambda注册到cancellationToken中
cancellationToken。注册(()= >;
{
//我们收到取消消息,取消任务完成源。任务
任务完成源。tryetscanceled();
});
vartask = LongRunningOperation(循环);
//等待两者中的第一个任务完成
varcompletedTask = awaitTask。WhenAny(任务,任务完成源。任务);
returnawaitcompletedTask
}
像上面的代码一样执行cancel命令:
publicationstatisycontask canceloncancelabletaskasync()
{
控制台。WriteLine(名称为(CancelanOnCancelableTaskAsync));
使用(VarCancelationTokenSource = NewCancelationTokenSource())
{
//听按键取消
变量键盘任务=任务。运行(()= >;
{
控制台。写线(“按回车键取消”);
控制台。read key();
//发送取消消息
取消令牌源。cancel();
});
尝试
{
//运行长时间运行的任务
varlongRunningTask = longrunningoperationwithchanctiontokenasync(100,cancellationTokenSource。令牌);
var result = awaitlongrunning Task;
控制台。WriteLine( "Result {0} ",Result);
控制台。写线(“按回车键继续”);
}
捕获(任务取消异常)
{
控制台。写线(“任务已取消”);
}
awaitkeyBoardTask
}
}摘要
在大多数情况下,我们不需要编写定制的可取消任务,因为我们只需要使用现有的API。但是知道幕后是怎么运作的总是好的。
●编号268,直接在此条输入编号
1.《cancellation 你不一定知晓的C#取消异步操作》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《cancellation 你不一定知晓的C#取消异步操作》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/jiaoyu/1054531.html