c# - 为 async void main 设置 ApartmentState

标签 c# async-await sta mta

我有一个 Windows 窗体应用程序。

现在我想使用一个async方法。

从 C# 7.1 开始,我可以使用 async Main 方法:
https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7-1

但是,现在我的 STAThread 属性被忽略,我的应用程序在 MTA 中运行。这是设计使然,还是我可以强制我的应用再次以 STA 模式运行?

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static async Task Main(string[] args)
{
    // returns MTA
    Console.WriteLine("{0}", Thread.CurrentThread.ApartmentState);
}

最佳答案

STA是您 promise 单个线程将操作 Windows 消息泵的线程(通常隐藏在对 Application.Run() 的调用之后)。当线程未被占用时,您将在线程上运行消息泵。

async 方法是这样一种方法,当它没有更好的事可做时,将释放它的线程以离开并做其他事情。

我无法使这两个概念保持一致。如果你想要 STA,你想要保留那个线程和泵消息。所以使用 async main 在那里没有意义。


在这种特殊情况下(各种初始化步骤可以从 await 中受益,然后是 Application.Run 我会使用 async Main < em>没有 STAThread 属性。然后我将显式创建一个专门用于运行 Windows 消息循环的 STA 线程。

没有规定程序中的第一个线程必须是 STA 线程,我认为这提供了最清晰的分离。如果您的 async Main 没有进一步有用的工作要做,您可能需要在 Main 和消息循环运行线程之间共享一个 TaskCompletionSource然后在 Application.Run() 返回时发出完成信号。

关于c# - 为 async void main 设置 ApartmentState,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47553489/

相关文章:

android - 使用 Kotlin Coroutine 从调用挂起函数的普通函数返回值

c# - 带有 Windows 窗体的 WPF - STAThread

c# - 防止事件产生另一个线程

c# - NUnit 异步测试 + RequiresSTA => 等待不在 STA 线程上返回

c# - 为什么这个 Observable.Generate 重载会导致内存泄漏? [使用时间跨度 < 15ms]

c# - 按降序排列日期

c# - "Atomically"更改 System.Threading.Timer

c# - 如何在 Bot Framework 的测试函数中访问用户和对话数据

rust - 如果参数是 Send,则返回 Future Send

c# - Task 返回异步方法的 ConditionalAttribute 的等价物