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将它们描述为异步的。