中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 開發技術 > 
  • 如何解決.NET Core中GetHostAddressesAsync引起的EnyimMemcached死鎖問題

如何解決.NET Core中GetHostAddressesAsync引起的EnyimMemcached死鎖問題

發布時間:2021-09-16 16:05:05 來源:億速云 閱讀:121 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關如何解決.NET Core中GetHostAddressesAsync引起的EnyimMemcached死鎖問題,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

在我們將站點從 ASP.NET + Windows 遷移至 ASP.NET Core + Linux 的過程中,目前遇到的最大障礙就是 —— 沒有可用的支持 .NET Core 的 memcached 客戶端。

我們一直用的是 EnyimMemcached ,在沒有其它選擇的情況下,我們自己嘗試著將 EnyimMemcached 遷移至 .NET Core。。。基于 .NET Core 修改好了代碼,在開發環境下測試通過,在 Linux 服務器上自己訪問很正常(沒有并發訪問量),但是只要接入一定的訪問量就會發生死鎖(deadlock),瀏覽器請求卡死。

這個問題困擾了我們很長時間,昨天才定位到是發生在將 memcached 服務器名稱解析為 IP 地址的時候。

var addresses = System.Net.Dns.GetHostAddressesAsync(host).Result;

這是我們在將 EnyimMemcached 遷移至 .NET Core 時修改過的代碼,之前調用的是同步方法:

var addresses = System.Net.Dns.GetHostEntry(host);

由于在 .NET Core Framework 的 System.Net.Dns 中沒有同步方法,只有異步方法,所以我們只能這樣調用異步方法。

看到上面的代碼,你也許會詫異:怎么用 .Result ,為什么不用 await ?不死鎖才怪呢。。。

你的詫異非常正確。我們也深知 .Result 的危害,在平時的代碼中堅決不用。但當時在修改 EnyimMemcached 的代碼時,由于這個方法是在 MemcachedClient 的構造函數中調用的,沒法改為 await 調用,被迫用了 .Result ,然后又把這個地方的修改給忘了。。。昨天才剛剛發現,立馬意識到罪魁禍首非常有可能就是這里的 .Result ,于是以此為突破口,想盡一切辦法實現在同步方法中調用異步辦法,并且在博問中尋求支援 —— 在同步方法中調用異步方法時如何避免死鎖問題 。

結果,用盡一切能想到與能找到的同步方法調用異步方法的方法,都沒能解決死鎖問題。如果實在找不到解決方法,我們準備采用最后一招也是最丑陋的一招 —— 不用 Dns.GetHostAddressesAsync() ,用 ProcessStartInfo 調用命令行命令解析 IP ,比如在 Linux 上用 getent hosts 主機名 。

在準備放棄之前,今天又想了想還有哪些可能帶來線索的地方漏掉了呢?突然想到有個重要地方竟然忘了,還沒看 Dns.GetHostAddressesAsync() 的源代碼實現。雖然不報太大希望,不就是個異步方法嗎,但還是要看一下。

于是從 github 上簽出 corefx 的源代碼,打開 Dns.GetHostAddressesAsync() 源代碼一看,感覺有點怪怪的,怎么用了 Task.Factory.FromAsync() ?

public static Task<IPAddress[]> GetHostAddressesAsync(string hostNameOrAddress)
{
  NameResolutionPal.EnsureSocketsAreInitialized();
  return Task<IPAddress[]>.Factory.FromAsync(
    (arg, requestCallback, stateObject) => BeginGetHostAddresses(arg, requestCallback, stateObject),
    asyncResult => EndGetHostAddresses(asyncResult),
    hostNameOrAddress,
    null);
}

開始沒反應過來,只是把這段代碼貼到博問的補充問題中,在貼完后突然反應過來了,咦,怎么沒有 async 關鍵字?方法名最后是 Async,我們一直以為是 async 方法,而且絲毫沒有懷疑過。。。

沒有 async ,只是返回參數是 Task 類型,那在同步方法中調用完全沒問題,只要在訪問 .Result 之前調用一下 .Wait() 方法就行了,于是改為下面的代碼:

Task<IPAddress[]> task = System.Net.Dns.GetHostAddressesAsync(host);
task.Wait();
var addresses = task.Result;

死鎖問題立馬解決!

方法名以 Async 結尾,卻不是 async 方法,當時的感想就是 —— 你的眼睛背叛你的心。如果不是我自己的誤解(只要以 Async 結尾,就應該是 async 方法),那就是一種流氓行為,就如 HttpClient 的流氓 —— 實現了 IDispose 接口,卻沒真正 Dispose 。

不管怎么樣,這個影響我們遷移至 .NET Core 的最大障礙終于消除了,值得慶祝!

支持 .NET Core 的 EnyimMemcached 的代碼還需要一些修改與完善,等修改好了,我們會把源代碼與 NuGet 包都發布出來。

關于“如何解決.NET Core中GetHostAddressesAsync引起的EnyimMemcached死鎖問題”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

牟定县| 麦盖提县| 新干县| 荔波县| 峨眉山市| 稻城县| 德州市| 青冈县| 舟曲县| 商城县| 元江| 虞城县| 湟源县| 新野县| 木里| 漳州市| 彭山县| 大名县| 孟津县| 沙湾县| 台南市| 仪征市| 东至县| 横峰县| 仁化县| 韶山市| 黄石市| 枞阳县| 太原市| 乐东| 富源县| 镇坪县| 徐闻县| 福安市| 东乌| 石门县| 通化县| 武山县| 普安县| 永吉县| 凤庆县|