实现执行异步 BigJob()
的无限运行任务的正确方法是什么?并可根据要求停止
提示 :我正在努力学习[a]新方法来更新我现有的策略。
我有这个简单的程序(测试人员),它有开始和停止按钮。
当按下开始时,我正在启动测试人员,该测试人员将查找并测试范围内的可用设备并在 无限 <中测试他们的地狱/ strong>在用户按下停止按钮之前的轮数。
重要的是,主进程/ action / bigJob()是和awaitble 异步进程。
所以我会伪代码整个事情
Start
Round 1 starts
Async Main job starts
Async connect
Async Read
Async Write
Async disconnect
Nobody cancelled me yet
Round 1 finishes
Round 2 starts
.
.
.
Round 2 finishes
Round 3 starts
.
Stop pressed, hence break out.
Stop
所以我使用BackgroundWorker
来实现无限循环,Async/Await
用于连接,读取,写入和断开连接我在C#
下编写的.Net 4.5
由于我的子任务(例如连接和.etc)为async
,因此我的主要任务是async
并按停止按钮停止我的过程,因为它消除了我有
while
循环
while (!bw.CancellationPending)
{
await MainTask();
...
}
但它并没有触发BackgroundWorker_RunWorkerCompleted
事件,因为后台工作人员没有工作,所以不会对我造成任何伤害因为它应该而我只是继续思考&#34;应该有更好的方法!&#34;。
所以,我一直在阅读有关这么多新想法的内容,比如为什么现在使用BackgroundWorker
,我们有Async/await
。有人说用Task.Run()
它是神奇的。我甚至阅读了关于这个我从未听说过的天赐TPL Dataflow的推荐和博客。到目前为止,我还没有找到一种结构化,文档化和布局为BackgroundWorker
的方法。 (除非它是如此简单或一个甚至不需要文档或.etc的衬里)所以,伙计们,这是什么解决方案。或者更好的方式来问:
实现执行异步 BigJob()
的无限运行任务的正确方法是什么?并可根据要求停止
答案 0 :(得分:8)
创建CancellationTokenSource并将其令牌传递给异步任务。这将允许您向异步任务发出信号,要求取消。更多信息:http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx
答案 1 :(得分:8)
您应该使用CancellationTokenSource
。但是不要将Token
传递给Task.Run
方法,也不要抛出异常。只需检查是否要求取消,然后停止。
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;
Task.Run(
async () =>
{
while (!ct.IsCancellationRequested)
{
await ConnectAsync();
await ReadAsync();
await WriteAsync();
await DisconnectAsync();
}
});
cts.Cancel();
当您将CancellationToken
传递给任务本身(Task.Run(async () => ..., ct)
)时,您无法在委托中使用它。如果取消在>> 任务开始运行之前被取消,它将仅取消该任务。在它开始之后,调用Cancel
将不起作用。
答案 2 :(得分:3)
我强烈建议大家阅读三种 Asynchronous Programming Patterns的不同方法以及使用最近和首选方法Task-based Asynchronous Pattern (TAP)
异步编程模型(APM)
描述使用IAsyncResult接口的旧模型 提供异步行为。不再推荐使用此型号 新发展。基于事件的异步模式(EAP)
描述用于提供异步的基于事件的遗留模型 行为。此模型不再推荐用于新开发。基于任务的异步模式(TAP)
描述基于的新异步模式 System.Threading.Tasks命名空间。此模型是 推荐 .NET Framework 4及更高版本中的异步编程方法 的 版本 强>
感谢@SKall指出我正确的方向。