首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异步/等待创建的C#任务未创建单独的线程。在脑海中有一张图片还能有什么用呢?

异步/等待创建的C#任务未创建单独的线程。在脑海中有一张图片还能有什么用呢?
EN

Stack Overflow用户
提问于 2021-01-14 01:08:45
回答 1查看 21关注 0票数 0

根据

If async-await doesn't create any additional threads, then how does it make applications responsive?

由await执行的C#任务...不会为目标任务创建单独的线程。然而,我观察到,这样的任务并不是每次都从同一个线程执行,而是可以切换它的线程。

我还是不明白,到底是怎么回事。

代码语言:javascript
复制
public class TestProgram
{
    private static async Task HandleClient(TcpClient clt)
    {
        using NetworkStream ns = clt.GetStream();
        using StreamReader sr = new StreamReader(ns);
        while (true)
        {
            string msg = await sr.ReadLineAsync();
            Console.WriteLine($"Received in {System.Threading.Thread.CurrentThread.ManagedThreadId} :({msg.Length} bytes):\n{msg}");
        }
    }
    private static async Task AcceptConnections(int port)
    {
        TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), port);
        listener.Start();
        while(true)
        {
            var client = await listener.AcceptTcpClientAsync().ConfigureAwait(false);
            Console.WriteLine($"Accepted connection for port {port}");
            var task = HandleClient(client);
        }
    }

    public async static Task Main(string[] args)
    {

        var task1=AcceptConnections(5000);
        var task2=AcceptConnections(5001);

        await Task.WhenAll(task1, task2).ConfigureAwait(false);
    }
}

此示例代码为端口5000和5001创建两个侦听器。其中每一个都可以接受多个连接,并独立于创建的套接字进行读取。

也许它不是“很好”,但它是有效的,我观察到,从不同套接字接收的消息有时在同一个线程中处理,用于执行的线程甚至会发生变化。

代码语言:javascript
复制
Accepted connection for port 5000
Accepted connection for port 5000
Accepted connection for port 5001
Received new message in 5 :(17 bytes):
Port-5000 Message from socket-1
Received new message in 7 :(18 bytes):
Port-5000 Message  from socket-1
Received new message in 7 :(18 bytes):
Port-5000 Message  from socket-1
Received new message in 7 :(20 bytes):
Port-5000 Message  from socket-2
Received new message in 7 :(18 bytes):
Port-5000 Message  from socket-2
Received new message in 7 :(18 bytes):
Port-5001 Message  from socket-3
Received new message in 8 :(17 bytes):
Port-5001 Message  from socket-3

(texts manually edit for clarity, byte lengths are not valid)

如果负载很重(我还没有测试它),那么需要多少线程才能执行这些并行任务?我听说过线程池,但不知道如何对它产生一些影响。

或者,问这个问题是完全错误的,我根本不必关心使用了什么特定的线程,以及涉及到多少线程?

EN

回答 1

Stack Overflow用户

发布于 2021-01-14 02:42:19

等待一个C#任务,由

执行...不会为目标任务创建单独的线程。

一个重要的更正是:任务不是由await“执行”的。Asynchronous tasks are already in-progress by the time they're returned。消费代码使用await来执行“异步等待”;即,暂停当前方法,并在该任务完成时恢复该方法。

我观察到,这样的任务并不是每次都从同一个线程执行,而是可以切换它的线程。

我观察到,从不同套接字接收的消息有时在同一线程中处理,用于执行的线程甚至会发生变化。

该任务不会在任何地方“执行”。但是async方法中的代码必须运行,并且必须在线程上运行。await captures a "context" when it pauses the method, and when the task completes it uses that context to resume executing the method。控制台应用程序没有上下文,因此该方法在任何可用的线程池线程上恢复。

如果负载很重(我还没有测试它),那么执行这些并行任务需要多少个线程?我听说过线程池,但不知道如何对它产生一些影响。

或者,问这个问题是完全错误的,我根本不必关心使用了什么特定的线程,以及涉及到多少线程?

您通常不需要知道;只要您的代码没有阻塞线程池线程,您通常就没问题。重要的是要注意,在执行I/O时,例如,在侦听/接受新的TCP套接字时,使用的线程为零。There's no thread being blocked there。线程池线程只有在需要时才会被借用。

在大多数情况下,您不必担心它。但如果你需要的话,thread pool有几个可以调整的旋钮。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65706556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档