【问题标题】:Why is this Task not Finishing before my code passes the Wait Command为什么在我的代码通过等待命令之前这个任务没有完成
【发布时间】:2016-05-04 14:44:29
【问题描述】:

我有一个任务,它运行一个循环并在每次迭代时延迟一段时间。一旦CancellationTokenSource 调用Cancel() 我希望我的主代码到Wait() 以完成Task.Delay(interval) 并且在我的代码继续之前退出循环的任务。我认为这段代码可以工作,但事实并非如此。

相反,我的主代码在循环退出之前传递了t.Wait()。为什么?

主要方法代码:

var cts = new CancellationTokenSource();
CancellationToken ct = cts.Token;

var t = Task.Run(() => { MyLoopTask(200, ct); });

// Prepare information

cts.Cancel();
t.Wait();    

// Send Information

任务代码

private async Task MyLoopTask(int interval, CancellationToken cancelToken)
{
    while (!cancelToken.IsCancellationRequested)
    {
        Debug.Print("   Still In Loop     ");
        // Do something
        await Task.Delay(interval);
    }

    Debug.Print("   cancelled     ");
    //Clean up
}

【问题讨论】:

  • ctsct 的邮政编码
  • 我想查看更多 Main Method 代码,以了解发生了什么。
  • 它很大,我会试着把它解析成有意义的块。
  • t 执行 MyLoopTask,它本身返回一个 new Task。您的所有代码都忽略了它。 t 几乎立即完成,因为 Task 几乎没有什么工作要做。

标签: c# task-parallel-library task


【解决方案1】:

您使用Task.Run 创建一个任务,该任务会触发并忘记您从MyLoopTask 返回的实际任务。

Task.Run 在这里是多余的。您可以直接调用MyLoopTask 并使用它返回的任务。

var t = MyLoopTask(200, ct);
// ...
t.Wait();

如果您仍然有理由使用Task.Run,您可以通过等待来确保代理等待实际任务:

var t = Task.Run(async () => await MyLoopTask(200, ct));
// ...
t.Wait();    

【讨论】:

  • 感谢您的回复。我明白你在说什么 - Task.Run 创建了一个启动我的方法的 Task 对象,并且由于该方法也是异步的 Task.Run 任务对象立即完成。这是有道理的。
  • @AdamHeeg 是的。从技术上讲,外部Task 在您方法中的第一个异步点完成,这是第一次等待Task.Delay
  • var t = Task.Run(() => MyLoopTask(200, ct)); 也可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多