【问题标题】:C# async await Task.delay in ActionC# async await Task.delay 在行动
【发布时间】:2013-07-10 02:44:21
【问题描述】:

我在让任务异步延迟时遇到了一些麻烦。我正在编写一个需要以数十万个异步执行脚本的规模运行的应用程序。我正在使用 C# Actions 执行此操作,有时,在执行特定序列期间,为了使脚本正确执行,它需要等待外部资源达到预期状态。起初我使用 Thread.Sleep() 编写了这个,但结果证明这是应用程序性能的鱼雷,所以我正在研究 async/await 以实现异步睡眠。但我无法让它真正等待暂停!有人可以解释一下吗?

static void Main(string[] args)
    {
        var sync = new List<Action>();
        var async = new List<Action>();

        var syncStopWatch = new Stopwatch();
        sync.Add(syncStopWatch.Start);
        sync.Add(() => Thread.Sleep(1000));
        sync.Add(syncStopWatch.Stop);
        sync.Add(() => Console.Write("Sync:\t" + syncStopWatch.ElapsedMilliseconds + "\n"));

        var asyncStopWatch = new Stopwatch();
        sync.Add(asyncStopWatch.Start);
        sync.Add(async () => await Task.Delay(1000));
        sync.Add(asyncStopWatch.Stop);
        sync.Add(() => Console.Write("Async:\t" + asyncStopWatch.ElapsedMilliseconds + "\n"));

        foreach (Action a in sync)
        {
            a.Invoke();
        }

        foreach (Action a in async)
        {
            a.Invoke();
        }
    }

执行的结果是:

同步:999

异步:2

如何让它异步等待?

【问题讨论】:

    标签: c# asynchronous action async-await


    【解决方案1】:

    您遇到了async void 的问题。当您将 async lambda 传递给 Action 时,编译器正在为您创建一个 async void 方法。

    作为最佳实践,您应该避免使用async void

    一种方法是让您的操作列表实际上是List&lt;Func&lt;Task&gt;&gt; 而不是List&lt;Action&gt;。这允许您将async Task 方法而不是async void 方法排队。

    这意味着您的“执行”代码必须等待每个Task 完成。此外,您的同步方法必须返回 Task.FromResult(0) 或类似的东西,以便它们匹配 Func&lt;Task&gt; 签名。

    如果您想要更大范围的解决方案,我强烈建议您考虑 TPL Dataflow 而不是创建自己的队列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2018-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多