在一個專案中,我發現了一個特殊的行為,然后使用來自 ThreadPool 的執行緒連接到 MySQL 實體;應用程式凍結,看起來是由于內部死鎖MySqlConnection.Open。當我手動創建執行緒并運行 Start 方法時,這不會發生。

所有執行緒都在MySqlConnection.Open方法中,并停留在那里。他們似乎沒有進一步列印出一些日志訊息 - 運行TestTask.
另一方面,運行TestThreads作業,然后我得到我期望的日志訊息:

我想了解為什么創建手動執行緒時 ThreadPool 會失敗?為什么 MySqlConnection 在一種情況下會死鎖,而在另一種情況下不會?
Please note that since we are testing against the same MySQL server, it is not a MySQL configuration issue. I also don't see how it can be ThreadPool starvation; we set the MinThread to 200. Also, since I never get a single Console.WriteLine in the TestTask case, there must surely be something else?
uj5u.com熱心網友回復:
MySql.Data里面有它的一些寫得不好的異步代碼(除問題是沒有一個Async方法實際上是異步)。
例如,此代碼使用 a 啟動異步作業Task,然后呼叫Task.Wait:https://github.com/mysql/mysql-connector-net/blob/4306c8484ec74b3ee1c349847f66acabbce6d63c/MySQL.Data/src/common/StreamCreator.cs#L98-L100
這就是“異步同步”,這是眾所周知的死鎖原因。問題很可能是執行緒池被你的用戶代碼阻塞了,所以需要完成的作業TcpClient.ConnectAsync無法排隊,所以沒有一個Tasks可以完成,所以沒有代碼可以向前推進。
您可以通過強制執行緒池擁有更多執行緒來解決這個問題(這在我的機器上有效,但它可能不是一個有保證的解決方案):
ThreadPool.SetMinThreads(500, 500);
// do NOT call ThreadPool.SetMaxThreads
您還可以切換到MySqlConnector,它正確實作了執行緒代碼,并且不需要SetMinThreads解決方法來運行。我已經添加使用的是什么MySqlConnector的異步方法的例子會是這樣。(披露:我是 MySqlConnector 的首席開發人員。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/359332.html
