c# - 在运行时链接 ContinueWith 任务

标签 c# asynchronous task

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

我相信这是使用 Task.ContinueWith 的主要候选者,并且我最初的硬编码功能使用此方法可以正常工作,但是当我尝试在运行时构建操作时,我遇到了问题因为我的任务运行顺序与我预期的不同。

我的类(class)看起来像:

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 的延续结束它。

理论上对我来说这看起来应该可行,但当我运行它时,我最终以错误的顺序运行延续。

我知道还有其他方法可以在不使用 ContinueWith 的情况下执行此操作,但我想看看我在使用此方法时出错的地方和方式。

最佳答案

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

关于c# - 在运行时链接 ContinueWith 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45235400/

相关文章:

c# - 将 JSON curl 转换为 C#

asynchronous - rust-tokio 流中的缓冲区有没有办法使用 &[u8] 以外的东西?

go - 是否可以将 Go Task runner 配置为使用文件扩展名 yaml?

c# - Socket.ReceiveAsync 什么时候同步返回?

c# - 循环内嵌套任务

c++ - 将 lambda 表达式传递给创建异步的函数

c# - Identity Server 4 与身份相关的范围请求,但没有 openid 范围

c# - 以编程方式触发 BSOD

c# - 有没有更好的方法来获取 XmlReader NodeType 属性?

javascript - React-native - 基于用户位置的drawerLabel