新方法:实现无限循环,可以在请求时停止
本文关键字:请求 实现 无限循环 新方法 | 更新日期: 2023-09-27 18:05:34
执行Async BigJob()
的无限运行任务的正确方法是什么?并可在请求时停止
提示: 我正在学习[a]新方法来更新我现有的策略。
我有这个简单的程序(测试器),它有一个开始和停止按钮。
当Start按下时,我将启动测试器,该测试器将查找和测试范围内可用的设备,并在无限中测试它们的数量,直到用户按下Stop按钮。
重要的是,主进程/action/bigJob()是一个可等待的异步进程。所以我将伪代码整个东西作为
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
用于连接,读取,写入和断开,我在.Net 4.5
C#
中编写了由于我的子任务,如连接和。等是async
,那么我的主要任务是async
和按停止按钮停止我的进程,因为它消除了无限的while
循环,我有
while (!bw.CancellationPending)
{
await MainTask();
...
}
但是它没有触发BackgroundWorker_RunWorkerCompleted
事件,这对我没有任何伤害,但是它让我很痛苦,因为后台工作器不工作,因为它应该,我只是一直在想"应该有一个更好的方法!"。
所以,我一直在阅读很多新的想法,像为什么要使用BackgroundWorker
既然我们有Async/await
。有些人说用Task.Run()
很神奇。我甚至阅读了关于这个我从未听说过的天赐的TPL数据流的推荐和博客。到目前为止,我还没有找到一种方法,它是结构化的,记录和布局作为BackgroundWorker
。(除非它是如此简单或一个行,甚至不需要文档或。等)所以,伙计们,这个问题的解决方案是什么?或者更好的问法:
执行Async BigJob()
的无限运行任务的正确方法是什么?并可在请求时停止
您应该使用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本身(Task.Run(async () => ..., ct)
)时,你不能在委托中使用它。只有在任务开始运行之前调用了,它才会取消任务。在它已经开始之后,调用Cancel
将没有任何效果。
创建一个CancellationTokenSource并将其令牌传递给异步任务。这将允许您向异步任务发出请求取消的信号。更多信息:http://msdn.microsoft.com/en-us/library/hh873177(v=vs.110).aspx
我强烈建议大家阅读一下三种不同的异步编程模式方法,以及最近和首选的基于任务的异步模式(Task-based Asynchronous Pattern, TAP)方法的使用
异步编程模型
描述使用IAsyncResult接口的遗留模型提供异步行为。不再推荐使用这种型号新的发展。基于事件的异步模式
描述用于提供异步的基于事件的遗留模型的行为。在新的开发中不再推荐使用此模型。任务型异步模式(TAP)
类描述新的异步模式System.Threading.Tasks名称空间。本型号为推荐型号 .NET Framework 4及以后版本中的异步编程方法< 版本/em> 。
感谢@SKall为我指明了正确的方向。