当前位置:首页 > 教育

cancellation 你不一定知晓的C#取消异步操作

链接: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

上一篇

谢霆锋晒泳照纹身 隔空证明与王菲情未变

下一篇

保姆随雇主27年 91岁保姆和91岁雇主之间有怎样的故事?

勒索病毒发生变种 尽快升级安装Windows操作系统相关补丁

勒索病毒发生变种 尽快升级安装Windows操作系统相关补丁

2008年5月15日,ransomware换了,尽快升级安装Windows操作系统补丁。ransomware变异了,真正的麻烦来了。据监测,在全球范围内爆发的WannaCry ransomware出现了一个变种:Wann...

王者荣耀之电竞传奇 探索“王者荣耀”电竞史上的传奇人物,他的操作出神入化多次获冠!

  • 王者荣耀之电竞传奇 探索“王者荣耀”电竞史上的传奇人物,他的操作出神入化多次获冠!
  • 王者荣耀之电竞传奇 探索“王者荣耀”电竞史上的传奇人物,他的操作出神入化多次获冠!
  • 王者荣耀之电竞传奇 探索“王者荣耀”电竞史上的传奇人物,他的操作出神入化多次获冠!

映像大厅任务 魔兽世界:巨大尖刺的双手大剑 强攻符文剑和巨魔杀戮者

运算器 计算机中绝大多数的运算任务都是由运算器完成的

  • 运算器 计算机中绝大多数的运算任务都是由运算器完成的
  • 运算器 计算机中绝大多数的运算任务都是由运算器完成的
  • 运算器 计算机中绝大多数的运算任务都是由运算器完成的
女子高速光脚开车 因操作不当致使车辆和路产受损

女子高速光脚开车 因操作不当致使车辆和路产受损

网络映射 5月23日,一名女子赤脚高速行驶,因操作不当导致车辆和道路财产受损。最近,一则关于一名女子赤脚高速行驶的新闻引起了关注。由于操作不当,刘女士造成车辆和道路财产损失,并对事故承担全部责任。女性赤脚高速行驶,操作不...

腾讯北京总部新大楼起火:工人操作不当引发 无人员伤亡

腾讯北京总部新大楼起火:工人操作不当引发 无人员伤亡

5月24日今天上午,有网友在微博上发布腾讯北京总部二期新楼视频,称部分消防队员和新浪员工已前往灭火。据了解,腾讯北京总部二期新楼位于海淀区软件园二期,附近有新浪、百度、网易等公司。  腾讯公关总监张俊金在微博上回应了这场大...

用DNA存储数据 建立一个以DNA为基础操作存储系统

用DNA存储数据 建立一个以DNA为基础操作存储系统

2008年5月24日,我们用DNA存储数据,建立了一个基于DNA的操作存储系统。用DNA存储数据是个疯狂的想法。微软研究院的计算机架构师表示,公司已经正式设定了一个目标,即在2020年之前在数据中心建立一个基于DNA的操...

上海百旺金赋科技有限公司 提醒 | 4月1日开票软件要升级!百旺金赋用户如何操作?