<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Don't Block on Async Code 不要阻止異步代碼

      翻譯自 Don't Block on Async Code (stephencleary.com)

      This is a problem that is brought up repeatedly on the forums and Stack Overflow. I think it’s the most-asked question by async newcomers once they’ve learned the basics.
      這是論壇和 Stack Overflow 上反復提出的問題。我認為這是異步新手在學習了基礎知識后最常問的問題。

      UI Example UI 示例

      Consider the example below. A button click will initiate a REST call and display the results in a text box (this sample is for Windows Forms, but the same principles apply to any UI application).
      請考慮以下示例。單擊按鈕將啟動 REST 調用并在文本框中顯示結果(此示例適用于 Windows 窗體,但相同的原則適用于任何 UI 應用程序)

      // My "library" method.
      public static async Task<JObject> GetJsonAsync(Uri uri)
      {
        // (real-world code shouldn't use HttpClient in a using block; this is just example code)
        using (var client = new HttpClient())
        {
          var jsonString = await client.GetStringAsync(uri);
          return JObject.Parse(jsonString);
        }
      }
      
      // My "top-level" method.
      public void Button1_Click(...)
      {
        var jsonTask = GetJsonAsync(...);
        textBox1.Text = jsonTask.Result;
      }
      

        

      The “GetJson” helper method takes care of making the actual REST call and parsing it as JSON. The button click handler waits for the helper method to complete and then displays its results.
      “GetJson” 幫助程序方法負責進行實際的 REST 調用并將其解析為 JSON。按鈕單擊處理程序等待幫助程序方法完成,然后顯示其結果。

      This code will deadlock. 此代碼將死鎖

      ASP.NET Example ASP.NET 示例

      This example is very similar; we have a library method that performs a REST call, only this time it’s used in an ASP.NET context (Web API in this case, but the same principles apply to any ASP.NET application):
      這個例子非常相似;我們有一個執行 REST 調用的庫方法,只是這次它在 ASP.NET 上下文中使用(在本例中為 Web API,但相同的原則適用于任何 ASP.NET 應用程序)

      // My "library" method.
      public static async Task<JObject> GetJsonAsync(Uri uri)
      {
        // (real-world code shouldn't use HttpClient in a using block; this is just example code)
        using (var client = new HttpClient())
        {
          var jsonString = await client.GetStringAsync(uri);
          return JObject.Parse(jsonString);
        }
      }
      
      // My "top-level" method.
      public class MyController : ApiController
      {
        public string Get()
        {
          var jsonTask = GetJsonAsync(...);
          return jsonTask.Result.ToString();
        }
      }

       

      What Causes the Deadlock 導致死鎖的原因

      Here’s the situation: remember from my intro post that after you await a Task, when the method continues it will continue in a context.
      情況是這樣的:請記住,在我 await 一個 Task 之后,當方法繼續時,它將在上下文中繼續。

      In the first case, this context is a UI context (which applies to any UI except Console applications). In the second case, this context is an ASP.NET request context.
      在第一種情況下,此上下文是 UI 上下文(適用于除 Console 應用程序之外的任何 UI)。在第二種情況下,此上下文是 ASP.NET 請求上下文。

      One other important point: an ASP.NET request context is not tied to a specific thread (like the UI context is), but it does only allow one thread in at a time. This interesting aspect is not officially documented anywhere AFAIK, but it is mentioned in my MSDN article about SynchronizationContext.
      另一個重要的點是:ASP.NET 請求上下文不綁定到特定線程(就像 UI 上下文一樣),但它一次只允許一個線程進入。AFAIK 在任何地方都沒有正式記錄這個有趣的方面,但在我關于 SynchronizationContext 的 MSDN 文章中提到了它。

      So this is what happens, starting with the top-level method (Button1_Click for UI / MyController.Get for ASP.NET):
      所以這就是發生的事情,從頂級方法(Button1_Click 用于 UI / MyController.Get 用于 ASP.NET):

      1. The top-level method calls GetJsonAsync (within the UI/ASP.NET context).
        頂級方法調用 GetJsonAsync (在 UI/ASP.NET 上下文中) 。
      2. GetJsonAsync starts the REST request by calling HttpClient.GetStringAsync (still within the context).
        GetJsonAsync 通過調用 HttpClient.GetStringAsync(仍在上下文中)來啟動 REST 請求。
      3. GetStringAsync returns an uncompleted Task, indicating the REST request is not complete.
        GetStringAsync 返回一個未完成的 Task,指示 REST 請求未完成。
      4. GetJsonAsync awaits the Task returned by GetStringAsync. The context is captured and will be used to continue running the GetJsonAsync method later. GetJsonAsync returns an uncompleted Task, indicating that the GetJsonAsync method is not complete.
        GetJsonAsync 等待 GetStringAsync 返回的 Task。上下文已捕獲,并將用于稍后繼續運行 GetJsonAsync 方法。GetJsonAsync 返回一個未完成的 Task,表示 GetJsonAsync 方法未完成。
      5. The top-level method synchronously blocks on the Task returned by GetJsonAsync. This blocks the context thread.
        頂級方法同步阻止 GetJsonAsync 返回的 Task。這會阻止上下文線程。
      6. … Eventually, the REST request will complete. This completes the Task that was returned by GetStringAsync.
        …最終,REST 請求將完成。這將完成 GetStringAsync 返回的 Task。
      7. The continuation for GetJsonAsync is now ready to run, and it waits for the context to be available so it can execute in the context.
        GetJsonAsync 的延續現在已準備好運行,它正在等待上下文可用,以便它可以在上下文中執行。
      8. Deadlock. The top-level method is blocking the context thread, waiting for GetJsonAsync to complete, and GetJsonAsync is waiting for the context to be free so it can complete.
        死鎖。頂級方法是阻止上下文線程,等待 GetJsonAsync 完成,而 GetJsonAsync 正在等待上下文空閑,以便它可以完成。

      For the UI example, the “context” is the UI context; for the ASP.NET example, the “context” is the ASP.NET request context. This type of deadlock can be caused for either “context”.
      對于 UI 示例,“context” 是 UI 上下文;對于 ASP.NET 示例,“context” 是 ASP.NET 請求上下文。這種類型的死鎖可能是由 “context” 引起的。

       

      Preventing the Deadlock 防止死鎖

      There are two best practices (both covered in my intro post) that avoid this situation:
      有兩種最佳實踐(在我的介紹文章中都有介紹)可以避免這種情況:

      1. In your “library” async methods, use ConfigureAwait(false) wherever possible.
        在你的 “library” 異步方法中,盡可能使用 ConfigureAwait(false)。
      2. Don’t block on Tasks; use async all the way down.
        不要阻止 Tasks;一直使用 async。

      Consider the first best practice. The new “library” method looks like this:
      考慮第一個最佳實踐。新的 “library” 方法如下所示:

      public static async Task<JObject> GetJsonAsync(Uri uri)
      {
        // (real-world code shouldn't use HttpClient in a using block; this is just example code)
        using (var client = new HttpClient())
        {
          var jsonString = await client.GetStringAsync(uri).ConfigureAwait(false);
          return JObject.Parse(jsonString);
        }
      }

      This changes the continuation behavior of GetJsonAsync so that it does not resume on the context. Instead, GetJsonAsync will resume on a thread pool thread. This enables GetJsonAsync to complete the Task it returned without having to re-enter the context. The top-level methods, meanwhile, do require the context, so they cannot use ConfigureAwait(false).
      這會更改 GetJsonAsync 的延續行為,使其不會在上下文中恢復。相反,GetJsonAsync 將在線程池線程上恢復。這使 GetJsonAsync 能夠完成它返回的 Task,而無需重新進入上下文。同時,頂級方法確實需要上下文,因此它們不能使用 ConfigureAwait(false)。

       

      Using ConfigureAwait(false) to avoid deadlocks is a dangerous practice. You would have to use ConfigureAwait(false) for every await in the transitive closure of all methods called by the blocking code, including all third- and second-party code. Using ConfigureAwait(false) to avoid deadlock is at best just a hack).
      使用 ConfigureAwait(false) 來避免死鎖是一種危險的做法。對于阻止代碼調用的所有方法(包括所有第三方和第二方代碼),必須對傳遞閉包中的每個await 使用 ConfigureAwait(false)。使用 ConfigureAwait(false) 來避免死鎖充其量只是一個 hack)。

      As the title of this post points out, the better solution is “Don’t block on async code”.
      正如本文的標題所指出的,更好的解決方案是 “Don't block on async code”。

      Consider the second best practice. The new “top-level” methods look like this:
      考慮第二個最佳實踐。新的“頂級”方法如下所示:

      public async void Button1_Click(...)
      {
        var json = await GetJsonAsync(...);
        textBox1.Text = json;
      }
      
      public class MyController : ApiController
      {
        public async Task<string> Get()
        {
          var json = await GetJsonAsync(...);
          return json.ToString();
        }
      }

      This changes the blocking behavior of the top-level methods so that the context is never actually blocked; all “waits” are “asynchronous waits”.
      這會更改頂級方法的阻塞行為,以便上下文永遠不會真正被阻塞;所有 “waits” 都是 “asynchronous waits”。

      Note: It is best to apply both best practices. Either one will prevent the deadlock, but both must be applied to achieve maximum performance and responsiveness.
      注意:最好同時應用這兩種最佳實踐。其中任何一個都可以防止死鎖,但必須同時應用這兩個選項才能實現最佳性能和響應能力。

      Resources 資源

      This kind of deadlock is always the result of mixing synchronous with asynchronous code. Usually this is because people are just trying out async with one small piece of code and use synchronous code everywhere else. Unfortunately, partially-asynchronous code is much more complex and tricky than just making everything asynchronous.
      這種死鎖始終是 synchronous 代碼與 asynchronous 代碼混合的結果。通常這是因為人們只是嘗試使用一小段代碼進行異步,并在其他任何地方使用同步代碼。不幸的是,部分異步代碼比僅僅使所有內容異步要復雜和棘手得多。

      If you do need to maintain a partially-asynchronous code base, then be sure to check out two more of Stephen Toub’s blog posts: Asynchronous Wrappers for Synchronous Methods and Synchronous Wrappers for Asynchronous Methods, as well as my AsyncEx library.
      如果您確實需要維護部分異步代碼庫,請務必查看 Stephen Toub 的另外兩篇博客文章:Asynchronous Wrappers for Synchronous Methods 和 Synchronous Wrappers for Asynchronous Methods,以及我的 AsyncEx 庫

      Answered Questions 已回答的問題

      There are scores of answered questions out there that are all caused by the same deadlock problem. It has shown up on WinRT, WPF, Windows Forms, Windows Phone, MonoDroid, Monogame, and ASP.NET.
      有大量已回答的問題都是由相同的死鎖問題引起的。它已出現在 WinRT、WPF、Windows Forms、Windows Phone、MonoDroid、Monogame 和 ASP.NET 上。

      posted @ 2024-09-26 17:25  Josen_Earth  閱讀(43)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 国产一区日韩二区欧美三区| 成人中文在线| 中文字幕自拍偷拍福利视频| 好吊妞视频这里有精品| 久久人人妻人人做人人爽| 国产成人av一区二区三| 日日碰狠狠添天天爽五月婷| 国产色婷婷精品综合在线 | 男女爽爽无遮挡午夜视频| 亚洲国产欧美在线看片一国产| 夜夜躁狠狠躁日日躁视频| 国产69精品久久久久乱码免费| 苍井空一区二区波多野结衣av| 日韩欧国产美一区二区在线| 日韩大片高清播放器| 久久永久视频| 92自拍视频爽啪在线观看| 四虎永久精品免费视频| 国产影片AV级毛片特别刺激| 日本中文字幕在线播放| 精品不卡一区二区三区| 欧洲成人在线观看| 起碰免费公开97在线视频| 免费人成视频网站在线观看18| 香港日本三级亚洲三级| 亚洲国产午夜精品理论片妓女| 国产精品一品二区三四区| 在线播放国产精品一品道| 国产精品无码av天天爽播放器| 国产精品久久久久久久9999| 亚洲高清WWW色好看美女| 亚洲午夜精品国产电影在线观看| 欧美成本人视频免费播放| 日韩黄色av一区二区三区| 92国产精品午夜福利免费| 亚洲一区二区av在线| 久久精品伊人狠狠大香网| 欧美日韩亚洲国产| 免费又黄又爽1000禁片| 亚洲无人区一区二区三区| 女高中生自慰污污网站|