C# 控制台应用程序中的单线程异步/等待

问题描述 投票:0回答:1

默认情况下,在控制台应用程序中,异步任务将在

ThreadPool
上运行,这意味着多个任务可以在不同线程上并行运行(如果您有多核处理器,则将会运行)。

如何禁止

Task
在我的控制台应用程序中并行运行(不使用互斥体;我不想处理公平问题并记住在各处锁定互斥体)?我希望一次只运行一项并发任务(即我希望这些任务是并发的,但不是并行的)。

我尝试将 ThreadPool 中的最大线程数设置为 1,但是 ThreadPool 运行的线程数不能少于 CPU 核心数,因此这不起作用。

c# async-await concurrency task
1个回答
0
投票

您可以使用 Stephen Cleary 的

AsyncEx
NuGet 包中找到的静态 AsyncContext 类在控制台应用程序上安装单线程同步上下文:

AsyncContext.Run(async () =>
{
    await Foo();
    await Task.WhenAll(items.Select(async item =>
    {
        var result = await Bar(item);
        DoStuff(result);
    }));
    await FooBar();
});

AsyncContext.Run
是阻塞调用,类似于
Application.Run
方法。它在当前线程上安装一个特殊的
SynchronizationContext
,就像
Application.Run
在 UI 线程上安装一个
WindowsFormsSynchronizationContext
一样。只要您直接在
await
委托内进行
AsyncContext.Run
一切操作(即没有
ConfigureAwait(false)
),每个
await
之后的所有延续都将在控制台应用程序的主线程上运行。 您的代码将是单线程的。任何内置的异步方法可能仍然在底层使用
ThreadPool
线程来完成它们的工作,但是 你的 代码不会观察这些其他线程,也不会受到它们的影响。

注意不要在任何地方使用

.Wait()
.Result
,否则你的代码将会死锁。如果您阻塞执行代码的单个线程,您的程序将停止运行。

© www.soinside.com 2019 - 2024. All rights reserved.