【问题标题】:Chain ContinueWith Tasks at runtime在运行时链 ContinueWith 任务
【发布时间】:2017-07-21 19:03:42
【问题描述】:

我正在尝试为我的视图模型创建一个辅助方法,该方法需要执行一组操作,并将阻止同时发生的其他操作集合。

我相信这是使用Task.ContinueWith 的主要候选者,并且我的原始硬编码功能使用此方法没有问题,但是当我尝试在运行时构建操作时,我遇到了一个问题,因为我的任务正在运行与我预期的不同。

我的班级看起来像:

internal abstract class ViewModel : IViewModel
{
    private readonly AutoResetEvent autoResetEvent = new AutoResetEvent(true);

    protected Task SynchronousTask(IList<Action> actions)
    {
        var initialTask = new Task(() => this.autoResetEvent.WaitOne());

        for (var i = 0; i < actions.Count; i++)
        {
            var i1 = i;
            initialTask.ContinueWith(task => actions[i1]());
        }

        initialTask.ContinueWith(task => this.autoResetEvent.Set());

        initialTask.Start();
        return initialTask;
    }
}

基本上我想等待AutoResetEvent 阻止任何正在运行的新任务,直到它被设置为止。然后,我循环遍历每个任务,将它们添加为初始任务的延续,最后以设置AutoResetEvent 的延续结束它。

在我看来,理论上它应该可以工作,但是当我运行它时,我最终会以不正确的顺序运行延续。

我知道有其他方法可以在不使用 ContinueWiths 的情况下做到这一点,但我想看看我在哪里以及如何使用这种方法出错。

【问题讨论】:

  • 如果您在循环中简单地使用await Task.Run(action),您可以摆脱所有这些代码。调用者将在执行到达第一个await 时返回一个任务。不需要事件或冷任务。
  • @PanagiotisKanavos 是的,我同意这会更好,并希望这是人们将来会做的事情,但我主要担心的是我哪里出错了,现在我看到这是一个愚蠢的疏忽。

标签: c# asynchronous task


【解决方案1】:

当您向同一任务添加多个延续时,例如在您的示例中 - 它们以特定顺序开始(据我所知,该顺序没有记录,您不应该依赖它- 但似乎它们是按后进先出的顺序启动的),但它们并没有按特定顺序运行。在它们启动后 - 它们都并行运行。因此,在您的情况下,所有操作和autoResetEvent.Set() 将在initialTask 完成后几乎同时执行。如果您需要顺序执行 - 只需将所有代码放在一个 Task 中并运行它,此处无需使用 ContinueWith。如果你真的想使用ContinueWith - 链延续(调用ContinueWith 上一个ContinueWith 的结果)。

【讨论】:

  • 啊,现在我知道我哪里出错了Task.
【解决方案2】:

您只需要链接到最后一个任务,而不是初始任务。 想象一下,将下一个任务与前一个任务挂钩,而不是将所有任务都与第一个任务挂钩。

public static Task SynchronousTask(List<Action> actions)
{
    var initialTask = new Task(() => autoResetEvent.WaitOne());

    Task lastTask = initialTask;
    for (int i = 0; i < actions.Count; i++)
    {
        int i1 = i;
        lastTask = lastTask.ContinueWith(task => actions[i1]()); // here
    }

    lastTask.ContinueWith(task => autoResetEvent.Set());

    initialTask.Start();
    return initialTask;
}

【讨论】:

    猜你喜欢
    • 2018-02-02
    • 1970-01-01
    • 2021-11-30
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多