【问题标题】:C# Asynchronous Socket Read Without Using Runtime's Threadpool不使用运行时线程池的 C# 异步套接字读取
【发布时间】:2016-08-09 14:58:44
【问题描述】:

我正在尝试创建一个可以处理相对大量客户端的套接字服务器。此类任务有不同的方法,首先是为每个传入连接使用单独的线程,其次是使用 async/await 模式。

第一种方法不好,因为线程数量相对较少,例如所有系统资源都会在上下文切换时丢失。

第二种方法从一开始就很好,因为我们可以拥有自己的线程池和有限数量的工作线程,因此调度程序将接收传入的连接,将它们添加到某个队列并调用异步套接字读取方法,这些方法反过来将从套接字并将此数据/错误添加到队列中以进行进一步处理(错误处理客户端响应,与数据库相关的工作)。

我找不到太多关于 async/await 的内部实现的信息,但据我所知,在使用非 UI 应用程序时,所有继续都是通过使用运行时线程池的 TaskScheduler.Current 完成的,因此它的资源是有限的。更大数量的传入连接将导致运行时的线程池中没有空闲线程,或者数量将如此之大以至于系统将停止响应。

在这个问题上 async/await 将导致与 1-client/1-thread 问题相同的问题,但是由于运行时线程池的线程可能不会像默认 System.Threading.Thread 那样占用那么多地址空间(我相信1MB 堆栈大小 + ~1/2MB 控制数据)。

有什么方法可以让一个线程在 10 个套接字上等待一些内核中断,这样应用程序将只使用我明确大小的线程池? (我的意思是,如果 10 个套接字中的一个有任何进一步的数据,一个线程将唤醒并处理它。)

【问题讨论】:

  • 异步套接字方法都使用内置于 .NET 线程池的 IOCP,它可能对您来说工作得很好。不需要你自己的线程池。
  • 我自己的线程池的需求来自于我需要对接收到的数据做很多工作并与客户交流,因为一些回调的东西甚至与我的应用程序无关是使用运行时的线程池制作的,我希望异步方法做的工作尽可能少。
  • 我在该描述中看不到任何需要自定义线程池的内容。内置的应该可以正常工作。

标签: c# multithreading sockets asynchronous


【解决方案1】:

在这个问题上 async/await 将导致与 1-client/1-thread 关注相同的问题

当线程到达异步运行的代码时,控制权返回给调用者,这意味着线程返回到线程池并可以处理另一个请求,因此它优于 1-client/1-thread,因为线程没有被阻塞.

有一些关于 asnyc/await 的有趣博客: 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多