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

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

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

      聊一聊 .NET 中的 CompositeChangeToken

      一:背景

      1. 講故事

      上一篇跟大家聊到了 CancellationTokenSource,今天跟大家聊到的是另一個話題叫組合變更令牌 CompositeChangeToken,當前我所有的研究都是基于dump分析之用,所以偏重的點自然就不一樣,如果純純的研究源碼那可能就是入門到放棄。。。接下來說下 CompositeChangeToken是干什么用的,你可以理解成觀察者模式,舉例:如果一個房子里面有幾顆炸彈,只要任何一顆炸彈爆炸,房子都會塌掉,任何關注這個房子的人都會有所變化(跑,叫,哭)... ,其中 CompositeChangeToken 就是觀察者集合,有了這個概念之后寫一段簡單的代碼。

      
      namespace BombHouseExample
      {
          internal class Program
          {
              static void Main(string[] args)
              {
                  // 創建多個炸彈(變化令牌)
                  var bomb1 = new BombChangeToken("炸彈1");
                  var bomb2 = new BombChangeToken("炸彈2");
                  var bomb3 = new BombChangeToken("炸彈3");
      
                  // 創建組合令牌 - 任何炸彈爆炸都會觸發房子倒塌
                  var houseToken = new CompositeChangeToken(new IChangeToken[] { bomb1, bomb2, bomb3 });
      
                  Console.WriteLine("房子里有幾顆炸彈,任何一顆爆炸都會導致房子倒塌!");
                  Console.WriteLine("觀察者(回調)已注冊:當房子倒塌時會有不同反應...\n");
      
                  // 注冊不同的觀察者反應
                  houseToken.RegisterChangeCallback(_ =>
                  {
                      Console.WriteLine($"【{DateTime.Now:HH:mm:ss}】 觀察者1: 驚聲尖叫!");
                  }, null);
      
                  houseToken.RegisterChangeCallback(_ =>
                  {
                      Console.WriteLine($"【{DateTime.Now:HH:mm:ss}】 觀察者2: 拼命逃跑!");
                  }, null);
      
                  houseToken.RegisterChangeCallback(_ =>
                  {
                      Console.WriteLine($"【{DateTime.Now:HH:mm:ss}】 觀察者3: 放聲大哭!");
                  }, null);
      
                  // 模擬炸彈爆炸
                  Console.WriteLine("\n3秒后炸彈爆炸...");
                  Thread.Sleep(3000);
                  bomb1.Explode();        // 任何一顆炸彈爆炸都會觸發所有回調
      
                  Console.WriteLine("\n按任意鍵退出...");
                  Console.ReadKey();
              }
          }
      
          /// <summary>
          /// 炸彈變化令牌 - 任何炸彈爆炸都會導致房子倒塌
          /// </summary>
          public class BombChangeToken : IChangeToken
          {
              private CancellationTokenSource _cts = new CancellationTokenSource();
              private string _bombName;
      
              public BombChangeToken(string bombName)
              {
                  _bombName = bombName;
              }
      
              /// <summary>
              /// 引爆炸彈
              /// </summary>
              public void Explode()
              {
                  Console.WriteLine($"【{_bombName}】爆炸了!");
                  _cts.Cancel();
              }
      
              public bool HasChanged => _cts.IsCancellationRequested;
      
              public bool ActiveChangeCallbacks => true;
      
              public IDisposable RegisterChangeCallback(Action<object> callback, object state)
              {
                  return _cts.Token.Register(callback, state);
              }
          }
      }
      
      

      從卦中看,是不是非常的形象,當然這不是本篇的主題,接下來簡單研究下底層。

      二:CompositeChangeToken 分析

      1. RegisterChangeCallback 干了什么

      這個方法在底層會做兩件事情。

      1. BombChangeToken 中注入CompositeChangeToken.OnChange 方法
      2. CompositeChangeToken 中注入 用戶自定義回調。

      千言萬語之前先來一張類圖,我花了點時間自己研究的,不知道對不對哈。

      手握地圖接下來就是如何眼見為實呢?先觀察源代碼。

      
      public IDisposable RegisterChangeCallback(Action<object> callback, object state)
      {
          this.EnsureCallbacksInitialized();
          return this._cancellationTokenSource.Token.Register(callback, state);       //第二件事
      }
      
      private void EnsureCallbacksInitialized()
      {
          if (!this.RegisteredCallbackProxy)
          {
              this._cancellationTokenSource = new CancellationTokenSource();
              this._disposables = new List<IDisposable>();
              for (int i = 0; i < this.ChangeTokens.Count; i++)
              {
                  if (this.ChangeTokens[i].ActiveChangeCallbacks)
                  {
                      IDisposable disposable = this.ChangeTokens[i].RegisterChangeCallback(CompositeChangeToken._onChangeDelegate, this);  //第一件事
                      if (this._cancellationTokenSource.IsCancellationRequested)
                      {
                          disposable.Dispose();
                          break;
                      }
                      this._disposables.Add(disposable);
                  }
              }
          }
      }
      
      

      有了源代碼的陪伴,接下來使用 dnspy 在 bomb.Explode() 處下斷點觀察,截圖如下:

      從卦中可以看到 BombChangeToken 注冊的果然是 OnChange,眼尖的朋友會看到這里有一個 CallbackPartition[16], 稍微解釋下,它是為了提高并發,將原來的 Registrations 拆分成了 16 個,相當于有 16 個 CallbackNode 分配器。

      接下來看另一張圖:

      從卦中可以看到這里也有一個自己的 cts,從 Id=3 可以知道里面有 3-1 個CallbackNode,即我們注冊的自定義回調。

      這里有一個小注意點,多個 BombChangeToken 和 單個 CompositeChangeToken 內部都有自己的 cts,這個在研究的時候不要以為是一個,搞得暈頭轉向的。

      2. Explode 是如何觸發的

      想了解這個觸發過程,畫一張序列圖如下:

      從卦中可以清晰的看到 BombChangeToken.TriggerChange() -> CompositeChangeToken.OnChange() -> CancellationTokenRegistration.Dispose() 的過程,接下來就是眼見為實環節了,在 CompositeChangeToken.OnChange 處下一個斷點觀察。

      最后就是要明白 Composite._cancellationTokenSource 中的一些重要調試信息,比如:

      • _threadIDExecutingCallbacks 當前執行取消操作的線程ID。
      • _executingCallbackId 當前正在處理哪一個CallbackNode 節點。

      上面的兩點信息在高級調試排查中非常重要,截圖如下:

      三:總結

      到這里就簡單的介紹完了,重點留意 _threadIDExecutingCallbacks_executingCallbackId 字段值是解決程序中疑難雜癥的關鍵。

      圖片名稱
      posted @ 2025-09-08 11:22  一線碼農  閱讀(595)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 亚洲av第二区国产精品| 少妇和邻居做不戴套视频| 国产偷国产偷亚洲综合av| 福利视频一区二区在线| 免费无码AV一区二区波多野结衣| 亚洲av高清一区二区| 亚洲成a人在线播放www| 国产精品入口麻豆| 99国产精品一区二区蜜臀| 午夜国产小视频| 伊人春色激情综合激情网| 亚欧洲乱码视频在线专区| 国产精品三级在线观看无码| 亚洲午夜福利网在线观看| 成人区人妻精品一区二区| 欧美做受视频播放| 99国精品午夜福利视频不卡99| 色综合夜夜嗨亚洲一二区| 另类 专区 欧美 制服| 国产免费一区二区三区在线观看| 小婕子伦流澡到高潮h| 亚洲午夜久久久久久噜噜噜| 2021国产成人精品久久| 99久久伊人精品综合观看| 成人亚洲精品一区二区三区| 久久国内精品一国内精品| 午夜成人精品福利网站在线观看 | 无码免费大香伊蕉在人线国产 | 久久精品免费观看国产| 国产线播放免费人成视频播放| 久久精品国产91精品亚洲| 亚洲欧美人成网站在线观看看| 在线观看成人av天堂不卡| 国产精品国产三级国产试看| 日韩日韩日韩日韩日韩熟女| 国内精品久久久久影院蜜芽| 欧日韩无套内射变态| 亚洲爆乳少妇无码激情| 国产精品一区在线免费看| 99久久国产综合精品成人影院| 97色成人综合网站|