C#异步等待Task.delay在操作中

本文关键字:操作 delay Task 异步 等待 | 更新日期: 2023-09-27 18:21:46

我在异步延迟任务时遇到了一些问题。我正在编写一个应用程序,该应用程序需要以数万/数十万异步执行脚本的规模运行。我使用C#操作来完成这项工作,有时,在执行特定序列的过程中,为了使脚本正确执行,它需要等待外部资源才能达到预期状态。起初我是用Thread.Sleep()写这篇文章的,但这对应用程序的性能来说是一个鱼雷,所以我正在研究异步/等待异步睡眠。但我不能让它真正地等待暂停!有人能解释一下吗?

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#异步等待Task.delay在操作中

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

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

这样做的一种方法是让你的动作列表实际上是List<Func<Task>>而不是List<Action>。这允许您对async Task方法而不是async void方法进行排队。

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

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