c# - await 在转移到与调用者相同的线程之前是否在内部创建另一个线程(对于 UI 应用程序)

标签 c# multithreading asynchronous async-await

我对 async/await 的了解是,当任务完成时,继续在调用 await 时的相同上下文中运行,在我的例子中,这将是 UI 线程。 但我的问题是,它是否会在 IO 完成后和移动到同一 UI 线程之前(在内部)创建一个新线程。

我正在分享一段代码。如果我点击一次这个按钮,它显示在执行 await 之前可用线程是 1023,但是之后,可用线程下降到 1022。虽然当我查看线程 id 时,它与 UI 线程相同。

    private async void button1_ClickAsync(object sender, EventArgs e)
    {
        int x, y;
        ThreadPool.GetAvailableThreads(out x, out y);
        textBox1.Text = x.ToString()+"..."+y.ToString();
        await Task.Delay(5000);
        ThreadPool.GetAvailableThreads(out x, out y);
        textBox1.Text = x.ToString() + "..." + y.ToString();
    }

但有趣的是,下次我单击此按钮时,可用线程数仍为 1023(等待之前和之后)。

最佳答案

But my question is, does it create a new thread (internally) after IO is complete and before moving to the same UI thread.

可能会临时使用其他线程,但您不必担心。

特别是,.NET 上的 I/O 通常通过作为线程池一部分的 I/O 完成端口。 I/O 线程会根据需要自动添加和删除。通常,I/O 在真正准备好返回您的代码之前还有一些额外的工作要做(例如,解析 HTTP 响应 header ),因此 很多 BCL I/O 代码将实际上使用 I/O 线程只是将工作排队到线程池。因此,I/O 代码经常(简要地)使用线程池工作线程。

此外,在这个特定示例中,我相信还有一个单独的计时器线程,它合并系统计时器。当然,这是一个实现细节,可能会发生变化。

所以,综上所述,其他线程可能会被创建/销毁/临时使用,但你不必担心。它们全部由 BCL 或 .NET 运行时以非常有效的方式管理,在重用线程(最小化流失)和最小化资源使用(尤其是内存)之间取得平衡。

关于c# - await 在转移到与调用者相同的线程之前是否在内部创建另一个线程(对于 UI 应用程序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39501929/

相关文章:

javascript - Jquery on Change 函数未在 asp.net MVC 中触发

c# - Umbraco - 从 Action 处理程序刷新内容树中节点的父节点

java - 如何与 NewFixedThreadPool 共享线程池

asynchronous - 由 webfontloader 加载的谷歌字体呈现阻塞

c# - 如何验证某些回​​调被异步调用(按顺序)

java - @Async 不适用于返回类型为 void 的方法

c# - Microsoft TextTransform 实用程序可以独立使用吗?

c# - Azure 存储 CDN 连接字符串

c++ - 设计可扩展的多线程应用程序

python - Flask-socketio 在后台线程中复制文件时丢失事件