簡體   English   中英

線程池飢餓 C# 異步套接字客戶端

[英]Threadpool Starvation C# Async Socket Clients

我編寫了一個連接到多個服務器(目前超過 50 個)的應用程序。 應用程序啟動緩慢。 這似乎是由於 ThreadPool 飢餓造成的,因為在采取不同的時間和 wireshark 跟蹤之后,一旦線程足夠高,問題似乎總是自行解決。 我進行了更改並將最小線程數增加了三倍,這完全解決了我的問題。 但這目前有效,但可能無法擴展到 100 個客戶端。

我到處都使用異步方法,並使用 System.IO.Pipelines API 進行套接字處理。 在啟動過程中,我有

var t = Task.Run(async () => 
{
    var client = new Client(IP, socket);
    try
    {
        await client.StartAsync(CancellationToken);
    }
    catch (Exception e)
    {
        Log.Error(e, "Unhandled exception");
    }
}

這是一次啟動所有客戶端連接。 我目前正在查看 App 的 rest 以查找任何可能會阻塞的方法/長時間運行的同步方法,這些方法會強制 ThreadPool 啟動一個新線程。 我不確定這是否有幫助,因為該應用程序啟動時似乎很慢,甚至在它進入任何可能導致工作隊列堆積的方法之前。

  1. 使用異步 API 和 System.IO.Pipelines 編寫的 Windows 服務是否應該能夠擴展到超過 50 個並發客戶端連接?
  2. 我是否應該重新設計啟動以更可控的方式這樣做? 只允許這么多的同時連接嘗試。 然后需要編寫邏輯來處理連接停止的情況(TCP 連接超時),這樣我們就不會卡在 5 個即將停止的連接后面

使用異步 API 和 System.IO.Pipelines 編寫的 Windows 服務是否應該能夠擴展到超過 50 個並發客戶端連接?

是的。

我是否應該重新設計啟動以更可控的方式這樣做? 只允許這么多的同時連接嘗試。

不,那應該無關緊要。 如果他們正在與不同的 IP 通話,那么您應該能夠毫無問題地同時連接它們。

根據您的運行時和實現,可能會發生初始連接的幾個同步方面。 第一個是 DNS 查找,(不幸的是)通常是同步的。 第二個是代理檢測(僅當您使用像HttpClient這樣的 HTTP 組件而不是像Socket這樣低於 HTTP 的組件時才適用)。

由於您觀察到的行為(即,如果您增加最小線程數,則工作正常),您幾乎肯定會在Client.ClientClient.StartAsync調用中的某處獲得一些同步代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM