【发布时间】:2019-08-05 08:35:47
【问题描述】:
我需要这样的代码:
module.StopAndWait();
module.DoSmth();
module.Resume();
我已经编写了 AsyncModel 类。我对“while (!isStopped);”行有疑问。在这一行,程序冻结。我认为 isStopped 必须改变,但事实并非如此。 我试图将 isStopped 声明为 volatile。 但无论如何程序在“while (!isStopped);”上有问题。
public class AsyncModel
{
bool run = false;
bool isStopped;
public async void Run()
{
if (run) return;
await Task.Run(() => progr());
}
public void StopAndWait()
{
run = false;
while (!isStopped) ;// <-- Problem
}
void progr()
{
isStopped = false;
run = true;
while (run)
{
Thread.Sleep(1500);
}
isStopped = true;
}
}
【问题讨论】:
-
当你使用异步方法时你想要并行,否则使用同步方法。
-
将 t 或 f 分配给 isstopped
-
volatile bool isStopped;,试试这个,run字段也是如此。创建自己的线程信号是一个坏主意,.NET 中已经有很好的类,请查看 ManualResetEvent/AutoResetEvent,理想情况下,您可能应该使用 CancellationToken 等完全使用任务。resume看起来喜欢吗? -
存在多个问题(例如,
async void的使用以及由于使用没有同步的变量而导致的竞争条件)。主要问题是没有任何东西调用Run所以StopAndWait永远不会结束。如果要等待任务终止,请使用await。所有这些代码都可以替换为单个await Task.Run(()=>progr())。如果你想在等待之前做点什么,var myTask=Task.Run(...); Something(); await myTask;. -
发出取消信号的正确方法是使用 CancellationTokenSource 并将 CancellationToken 传递给
progr。检查Enabling Progress and Cancellation in Async APIs
标签: c# async-await