【问题标题】:Why isn't a Task awaited before it get's cancelled?为什么任务在被取消之前没有等待?
【发布时间】:2015-09-15 21:45:06
【问题描述】:

我需要编写一个具有一些复杂行为的服务,例如同时执行的任务,但我遇到了问题。

我在 xUnit 中编写了一个示例来向您展示问题。

1 想在后台执行一个任务,最终启动一些子任务。 在某个时刻需要取消任务。

因此,我准备了以下内容:

[Fact]
public void ShouldWaitUnitTaskCompleted()
{
    Task.Factory.StartNew(() =>
    {
        while (!cancellationTokenSource.IsCancellationRequested)
        {
            Task.Delay(10000).Wait();
            TaskIsCompleted = true;
        }
    }, cancellationTokenSource.Token);

    Thread.Sleep(3000);

    cancellationTokenSource.Cancel();

    Assert.True(TaskIsCompleted);
}

}

但是,xUnit 在 3 秒后完成(我的线程休眠)。 在我的任务中,我有一个循环说,只要它不是取消请求延迟 10 秒。

所以我期望的行为是:

  • 启动应用程序。
  • 启动任务(因为没有取消请求,所以会开始延迟 10 秒)。
  • 等待 3 秒,然后取消令牌。
  • 等待延迟 10 秒的任务完成,然后退出。

为什么我的代码没有等待 10 秒帧过去?

【问题讨论】:

  • 当主(前台)线程在 3 秒后已经退出时,不存在后台线程。你的应用程序已经死了。您必须 Thread.Sleep 主线程 7 秒以上才能恢复其他工作。

标签: c# multithreading task-parallel-library


【解决方案1】:

您创建的不是await 您的Task。因此代码的执行将继续到Thread.Sleep(3000)

【讨论】:

    【解决方案2】:

    Cancel 表示已请求取消。

    在允许取消代码继续执行有用的事情之前等待所有任务完成 - 如果您确实想要等待这些任务响应,已经有机制供您单独执行此操作。所以Cancel 只做了一项工作,而且做得很好。

    【讨论】:

    • 这些机制是什么?
    • @Complexity - Task.Wait(或await)用于单个任务。 Task.WaitAllTask.WhenAll 用于多个任务 - 取决于您希望如何构建其余代码。
    • 谢谢,我会深入研究这个。这让我发疯了,但你对我说得很清楚:-)
    猜你喜欢
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 2022-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多