从头开始异步处理

Async processing from scratch

我有以下名为 Pluck 的 class:

internal static void Work()
{
    Task[] tasks = new Task[5];
    for (int i = 0; i < tasks.Length; i++)
    {
        tasks[i] = SumAsync();
    }
    Task.WhenAll(tasks);
}

private static async Task<int> SumAsync()
{
    return await Task.Run(() => { return OnePlusOne(); });
}

private static int OnePlusOne()
{  return 1+1;  }

还有我的主要方法:

static void Main(string[] args)
{
    Pluck.Work(); 
}

我遗漏了一些东西,因为我在 OnePlusOne 中切换了一个断点,但从未被击中。

Task.WhenAll(tasks) 是一种 async 方法,因此 return 是一种 Task。您需要 await 该任务以确保您仅在所有任务完成后才继续。目前,您的应用程序可能会在这些任务有机会 运行.

之前结束

这导致用 async 关键字标记 Work 并使其 return 成为 Task 本身:

internal static async Task WorkAsync()
{
    Task[] tasks = new Task[5];
    for (int i = 0; i < tasks.Length; i++)
    {
        tasks[i] = SumAsync();
    }
    await Task.WhenAll(tasks);
}

因为你不能在 Main 中使用 await 你需要同步等待 Wait:

static void Main(string[] args)
{
    Pluck.WorkAsync().Wait(); 
}

如果单个 await 是您在方法中所做的最后一件事(如在您的 SumAsync 和我的 WorkAsync 中),您可以删除它和 async 关键字,而只是 return 任务。这 稍微 提高了性能。更多信息 here.


注意:您应该只在非常特殊的情况下(比如在 Main 内)阻塞带有 Wait 的任务,因为它可能导致死锁。更好的解决方案是使用 AsyncContext.