C# 新方法:实现可根据请求停止的无限循环
实现执行异步C# 新方法:实现可根据请求停止的无限循环,c#,.net,multithreading,asynchronous,async-await,C#,.net,Multithreading,Asynchronous,Async Await,实现执行异步BigJob()的无限运行任务的正确方法是什么?并可根据要求停止 提示:我正在尝试学习更新现有策略的新方法 我有一个简单的程序(测试仪),它有一个开始和停止按钮 当按下开始时,我将启动测试仪,该测试仪将查找并测试范围内的可用设备,并在无限轮数中测试这些设备,直到用户按下停止按钮 重要的一点是,主进程/action/bigJob()是可等待的异步进程 因此,我将伪代码作为 Start Round 1 starts Async Main job starts A
BigJob()
的无限运行任务的正确方法是什么?并可根据要求停止
提示:我正在尝试学习更新现有策略的新方法
我有一个简单的程序(测试仪),它有一个开始和停止按钮
当按下开始时,我将启动测试仪,该测试仪将查找并测试范围内的可用设备,并在无限轮数中测试这些设备,直到用户按下停止按钮
重要的一点是,主进程/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/wait
来连接、读取、写入和断开连接,我在C#
中编写了.net4.5
由于我的子任务(如Connect和.etc)是async
,因此我的主要任务是async
,按下停止按钮会停止我的进程,因为它消除了我的无限而循环
while (!bw.CancellationPending)
{
await MainTask();
...
}
但是它没有触发BackgroundWorker\u RunWorkerCompleted
事件,这对我没有任何伤害,但是它正在杀死我,因为后台工作人员没有按预期工作,我只是一直在想“应该有更好的方法!”
所以,我一直在读很多新的想法,比如既然我们有了Async/await
,为什么还要使用BackgroundWorker
。有些人说使用Task.Run()
这很神奇。我甚至读过关于这一天赐的建议和博客,我从未听说过。到目前为止,我还没有找到一种像BackgroundWorker
那样结构化、文档化和布局的方法。(除非它是如此简单或一行程序,甚至不需要文档等)那么,伙计们,这个问题的解决方案是什么。或者更好的提问方式:
实现执行异步BigJob()
的无限运行任务的正确方法是什么?并且可以根据请求停止创建并将其令牌传递给异步任务。这将允许您向异步任务发出取消请求的信号。更多信息:您应该使用。但是不要将令牌
传递给任务。运行
方法,不要抛出异常。只需检查是否请求取消,然后停止
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;
Task.Run(
async () =>
{
while (!ct.IsCancellationRequested)
{
await ConnectAsync();
await ReadAsync();
await WriteAsync();
await DisconnectAsync();
}
});
cts.Cancel();
当您将a传递给任务本身(Task.Run(async()=>…,ct)
)时,您不能在委托内部使用它。只有在任务开始运行之前调用了取消,它才会取消任务。开始后,调用Cancel
不会有任何效果。我强烈建议大家阅读三种不同的方法,以及最新和首选方法的使用
异步编程模型(APM)
描述使用IAsyncResult接口来
提供异步行为。不再推荐使用此型号
新的发展
基于事件的异步模式(EAP)
描述基于事件的旧式模型,以提供异步
行为。对于新开发,不再建议使用此模型
基于任务的异步模式(TAP)
描述基于的新异步模式
System.Threading.Tasks命名空间。此型号为推荐型号
在.NET Framework 4及更高版本中进行异步编程的方法
版本
感谢@SKall为我指明了正确的方向。这就是我将代码修改为的方式。如果我错了,请纠正我。我已将我的开始按钮绑定到一个async
方法,该方法使用一个可等待的Task.Run(..,cancellationToken)
。在这个Task.Run()
中,我将我的while(true)
放在它的第一行,如果cancellationToken.ThorwIfCancellationRequest()
触发,它就会停止。这样做不会停止正在运行的任务。请参见此处:如果取消操作仅用于主循环,则最好使函数同步。主要任务是异步的,所以它已经处理好了。@SKall什么?哪些功能?连接、读取等。?如果函数是异步的,那么一切都应该是异步的。如果他们不是,那么什么都不应该是。OP将它们描述为异步的。