2018年10月30日 星期二

dotTrace 心得 Filter

dotTrace 心得 Filter

GC

  • GC 在dotTrace的計算是將 Blocking GC的時間再加上 Background GC的不重覆時間,這邊指的不重覆時間是指Blocking GC可能是Background GC引起的,因此在算時間上,要扣掉重覆的部分。
  • GC Blocking 指的是GC造成 Blocking 的時間,若沒有造成Blocking,如背景,就不計算。
  • GC Background 單純指的是 Background GC執行的時間。
  • GC Blocking during Background 指的是因為Background GC 所引發的 GC,這就是因為執行GC2所引起的GC0,1回收。
  • GC Wait 計算時間的方式是將受到GC影響的Thread的時間 + Background GC 執行的時間 進行統計。也就是若在同一個時間下,Thread1,2都受到GC影響而Block,那這兩個Thread受到影響的時間都要加總起來再加上Background GC的時間。

Thread Status

  • 當選擇Thread做為Filter時,可以選擇更細的項目,如 Running:CPU Core。透過 Running:CPU的分析,我們可以評估以下兩個狀況。
    1. 我們是否要將流程限制在一個CPU上執行,因為在太多Core上交互執行造成不必要的Loading
    2. 我們是否要將流程分散在多個CPU上執行,因為在執行時有多個CPU都是閒置的。

dotTrace Find the Cause of a UI Freeze

dotTrace 學習心得

Find the Cause of a UI Freeze

  1. 選擇不需要的Thread,將它從我們的列表上移除。這邊選擇的方式是吃經驗值的,你必需知道你用了一個Background,所以會有一個Thread Pool的資料。你知道Finalizer是程式關閉的所以不用注意。你也裀道Garbage Collection是處理記憶體管理的,所以你可能要先留著,不要移除。
  2. 觀察Thread Pool的Thread,這是Background工作用的Thread。可以發現有短暫的暫停,
  3. 除了Thread Pool的時間Bar外,還可以觀察兩個額外的Bar,一個是UI Freeze的Bar(看上面的符號應該是紫色的),這是當UI的Message Pumping在200ms沒有作動時,就會開始產生。另外一個是GC發生的Bar(從上面的符號看應該是土黃色)
  4. 直接從UI Freeze Filter上面點選,表示要看整個UI Freeze的區段
  5. 先觀察是不是GC Block造成的。先從Event上選擇 Garabage Collection再選下面SubSystem的Blocking就可以查看因為Blocking造成的時間。若是時間很短,再查別的。

重要Panel意義

Call Tree

指定的Thread裡所呼叫的方法樹。會從最上層的呼叫一路列下來。可以從這裡觀察方法的呼叫階層及在特定階層時,該方法及其子方法的所需時間

Call Stack

列出指定Thread裡所有被呼叫的方法。會將所有的方法整合在一起,沒有誰呼叫誰的關係。系統會自動將時間佔據最久的放在最上面。

Call Tree vs Call Stack

可以想成一個是方法的TreeView,一個是方法的ListView

Interval Filters

  • 所謂的Interval Filters就是將特殊事件發生時的時間收集起來。
  • 當點選UI Freeze Filter時,會自動在Thread Bar上框出此種事件發生的時間點,也可以觀察到它是間斷發生的。
  • 若點選UI Freeze Filter及其他Filter時,就代表在UI Freeze 下又執行其他Fitler的狀態。

.Net CLR Backgorund GC

.Net CLR Backgorund GC

  • 背景記憶體只針對Generation2使用
  • 在回收時,可能視需要也同時回收 GC0 及GC1。這個就暫時回收。
  • 暫時回收是一種前景回收,這種回收進行時所有的 Managed 執行緒都會暫停。
2018年10月28日 星期日

Premiere 教學心得 (五) - Adjust the timing of your edits

Trim clips on the Timeline

  1. 要調整Clip的長度,最簡單的方式就是直接點選後,拖動Clip的尾部。拖動的時候,會看到Program上的左半邊影像會直接顯示該Clip的最後一個Frame,而右半邊會顯示下一個Clip的第一個Frame
  2. 當直接拉動尾端時,縮短的部分會在Timeline上留下Gap。這時若有開啟Timeline上的Ripple Edit Tool,就會發現在拉動尾端後,所有後面的Clip會全部往前填滿此Gap
  3. 與Ripple Edit Tool 類似的,還有Rolling Edit Tool。使用此種工具拉選時,會同時縮短其中一個Clip的長度並延伸另一個Clip的長度。
  4. 使用鍵盤上的Q,可以將時間線前的Clip刪除。使用鍵盤上的W,可以將時間線後的Clip刪除。不過要注意音規也會一併刪除。若不想要動到音軌,則可以使用軌道前的鎖,先鎖起來再剪

Trim clips in the Program Monitor

  1. 選擇一個Clip的尾端,使用滑鼠點兩下就可以讓Program進入剪輯模式。在此模式下,可以微調兩個Clip之間的長度。也可以使用底下的按鈕來調整Frame。
  2. 若按下Ctrl 鈕再使用滑鼠拖曳,可以發現會變成黃色,也就是Ripper Edit Tool 的模式。

Use Sync Locks and Track Locks

  1. 在剪輯時,有時想要其他軌一起移動,有時又不想。一般影音預設就是會一起移動的。若不想要,就是使用 Link Selection 來改變。
  2. 當有字幕軌或是其他軌時,由於是後面才加上去的,所以我們在使用 Ripple Edit Tool 修剪時,這些軌也會一併往前,但我們可能不想要這麼多。所以我們就可以關掉這些軌的 Sync Lock

總結會影響剪輯的有以下幾個選項及功能

  • Linked Selection
  • Ripple Edit Tool
  • Rolling Edit Tool
  • Toggle Track Lock
  • Toggle Sync Lock
  • Link
  • UnLink

dotTrace心得 (二)

Timeline的用途

  1. 找出程式運行中,CPU用量高的原因
  2. 找出運行最慢的方法以及它呼叫的對像
  3. 找出造成UI凍結的原因
  4. 找出記憶體被超量使用的原因

使用Timeline的步驟

  1. 將時間拉到CPU用量高的位置
  2. 從CallStak中找出CPU用量比率最高的方法
  3. 從CallTree觀察此方法呼叫的方法是否有異常
  4. 點選CallTree中的方法時,SubSystem會即時計算,此時可以確認不合理的地方

使用Timeline的操作提示

  1. 將Events Panel 切換到 Memory Allocation,則所有的計量單位就會變成 mb。
  2. 在Memory Allocation下,原本每個方法所佔用的時間,就都會變成使用的記憶體
  3. 在SubSystem下,可以觀察到,配置的記憶體的型別是什麼。

Premiere 教學心得 (四) - Work with graphics and titiles

Work with image files

  1. 可以直接從Media Browser 將圖片 Import 到 Project 中再加入到 Timeline 中,也可以直接從 Media Browser拉到 Timeline
  2. 圖片拉進來後,可以調整圖片的持續長度,與影片不同,可以一直拉長。在用滑鼠拉動時,可以看到圖片時間及總長度。
  3. 圖片拉到Timeline中,預設5秒鐘。這可以從Edit -> Preferences -> Timeline -> Still Image Default Duration 進行設定

Create a new title

  1. 要新增文字,可以先在面版的上方選擇Graphic工作面版,開啟Essential Graphics面版進行文字的選取及編輯 。
  2. 先在Essential Graphics的 Browse 中選擇文字的形式,加到Timeline中,再點選文字就會出現Edit的面版進行編輯
  3. 在Edit中可以調整字型、顏色,所有影片中所用的字全部會出現在此。文字框本身也有Layer的概念,因此可以直接在這邊做移動。
  4. 我們也可以透過 Program 的Pen工具來產生個矩形。畫出矩形後,會直接放在Edit的項目中,我們可以調整它填滿的顏色,外形和Shadow.
    Rectange Proeprty

Change the size of clips

  1. 在Project中點擊照片時,可以從Source中看到照片原始的大小。有時我們在Timeline中的照片有修改過,因此從Project中可以檢視原始。
  2. 當加入太大的影像到Timeline中時,我們可以點擊選此照片,然後右鍵選擇 Scale To Frame,就可將圖片放大或縮小到符合影像的大小。
  3. 當加入的圖片因為比例不符合而造成左右黑邊或是圖片的內容有角度不夠水平時,可以在Timeline中,點選此圖片,在Source中切到Effect Control面版。這邊可以針對圖片來進行 Position (位置), Scale (縮放), Rotate (角度) 的修改。注意:在修改的時候,由於要看到修改後的結果,所以要在Timeline中把目前的影像位置移到要修改的圖片上,這樣就可以一邊控制Effect Control面版中的屬性,另一邊看著 Program 中修改後的結果。
  4. 在調整Rotate時,可以點選值出現Scarlet後,在用鍵盤的上下進行調整,若控下Ctrl鍵,則可以進行微調。
  5. 當一次加入大量照片,尺寸有不合時,可以使用滑鼠多選後,在一次使用滑鼠右鍵的 Scale To Frame 一次調整大量影像。

Premiere 教學心得 (三) - Learn editing skills

Create a new sequence

  1. 使用Project Panel右下角的new item 新增一個 sequence。系統會接著問這個sequence的影像格式,注意,這邊指的是輸入的格式而不是最後影像輸出的格式。
  2. 當使用者將影像新增的sequence時,會檢查這個影像的格式。如果不符合,會跳出視窗詢問使用者是否要做轉換。

Add clips to a sequence

  1. 將Clips加到sequence中只要用滑鼠拖拽即可。
  2. Clip可以覺Source Panel中檢視,如果有做 in out Mark。拖到Timeline上時,就只會將Mark的區域加入。
  3. 從Source Monitor拖時,可以選擇只要音頻或是影像

Remove clips from a sequence

  1. 在Timeline中選擇clip後,按下Delete。就可以移除,但會留下空的白區域
  2. 若在刪除時使用Shift + Delete ,則不會留下空白
  3. 也可以使用Timeline左邊的 Track Select Forward To 來進行選擇,此時會將選擇的Clip一直到影片結束的Clip全部選擇
  4. 若在使用Track Select Forward To 時,加上Shfit的話,會發現滑鼠的Icon從兩個箭頭變成一個。這時候再去做選擇Clip,會發現依然是向前選取到影像結束,但只會選擇我們點的軌道,其他的軌道不會一起點選。
  5. 在點選Clip時(使用一般點選,不是Track Select Forwrard To),會將此Cilp相對的影像和聲音一起選擇,則可以透過Timeline上的 Linked Selection 按鈕切換。若沒開啟這功能,則點選那一個軌道的Clip,就只有那一軌的Clip被點選,不會一併點選其他軌。

Move clips in a sequence

  1. 將一個Clip移到另一個Clip上,原本Clip的位置會空出來,像Delete一樣。而被蓋掉的Clip,若長度超過移動過來的Clip,則沒有被蓋到的地方會視為新的Clip,就是長度比原本的短。因此,若將一個短的Clip移到一個長的Clip的中間,可以看到長的Clip會被剪成前後兩斷。
  2. 按住Ctrl後移動Clip,就可以不覆蓋原本的Clip,而是將被蓋掉的Clip往前移動。不過,要是放置的位置是在一個Clip的中間,此Clip還是會被分成前後兩段,只是沒有任何資料會被蓋掉。
  3. 可以使用左邊的 Razor Tool 來切割 Clip。在切割Clip時,會依據是否有選擇音軌來決定切割影像Clip時,是否連同聲音Clip一起切割。
  4. 選擇Clip時,是否會連同其他軌的Clip一起選,取決於是否有開啟 Linked Selection。另外,我們也可以在Clip上按右鍵,選擇UnLink 切斷影音之間的關聯,或是點選影音兩個clip再點選Link建立兩者間的關聯。

Make simple audio adjustments

  1. 可以透過Audio Maxier Panel 來調整每個音軌的聲音的大小,左右聲音的平衝,要Solo某一個音軌,或是Mute送一個音軌。

Premiere 教學心得 (二) - Explore Premiere Pro panels

Work Explore Panels

  • Work with the Project panel

    1. 點選Project視窗的左下角有兩個Icon,一個是Icon View,一個是List View。透過這兩個Icon可以切換資源的顯示方式。
  • Source and Program monitors

    1. 在Project Panel上選取Resource點選後,就可以在Source Monitor上觀看
    2. 在Source Monitor上,若是影片可以播放,可以透過Button來做細微的移動(前後一個 Frame)。或是使用鍵盤的左右鍵
    3. 在Source Monitor上,可以在影片上加上Mark。Mark標註的時間會在右下角的Duration顯示。透過右鍵選單的Mark Split還可以針對影像和聲音軌進行不同的Mark
    4. 在Program Monitor可以看整個Sequence,也可以在上面加Mark。
    5. 在Program Monitor上,可以使用 Clear In & Out 在清除所有的Mark
  • Explore the Timeline panel

    1. Timeline Panel 上的影像軌眼球可以決定播放時是否有影響
    2. Timeline Panel 上的聲音軌的M可以決定是否要靜音
    3. 鍵盤上的 ` 可以快速將目前的Panel全螢幕畫,再按一次回到原先的配置
    4. Timeline Panel 上的Snap按鈕可以在移動Clip時,自動和前一個Clip貼齊。關掉的話,就會隨著使用者放那裡就那裡。
    5. 在Timeline Panel 上,按住 alt 再滾滾輪,可以放大縮小時間軸

Premiere 教學心得 - Create a project and import a clip

Create a project and import a clip

  • Create a Porject
    心得:檔案要先加入到專案中,才能拿來用。專案內有對於檔案的連結,但沒有檔案的實體。

    1. 點選一個new project
    2. 取名之外,可以點選旁邊的Browser,選擇要存放檔案的位置
    3. 其他選項不管,這樣就產生一個空的premiere的空project
    4. 進專案後,點左下角的MediaBrowser,可以選擇自己的素材
    5. 在MediaBrowser可以自己選擇素材,也可以按Ctrl+A全選。選擇好後,使用滑鼠右鍵 import ,就可以加入此專案的剪輯中
    6. 在專案的剪輯中,只要點兩下,就能在Source Monitor中檢視
  • Workspace overview

    1. 中間上方是各式工作區的Layout (Assembly,Editing,Color,Effects…)。點選後,就會直接採用此種Lauyout.
      當然使用者也可以任意修改。要是想要後悔的話,可能再按弰鼠右鍵選擇Reset to SaveLayout。就可以還原了。
    2. 找不到某一個Panel時,可以從畫面上方工具列的Window內尋找,選擇後,就會將此Panel帶到畫面最上層
  • Import media

    1. 在Porject面版內,除了從MediaBrowser匯入的資源外,也可以透過右鍵產生資料夾,這種資料夾稱為Bin。
    2. Bin用來分類資料用。
    3. 也可以直接選擇要移動的資源,拖到Panel右下的Create New Bin,被選定的資源就會移動過去,並且要求為此Bin命名
    4. 在Project面版內改的名字不會影響到實體檔案,所以可以依照自己的分類命名
  • Build a sequence

    1. 可以在Project面版中,選取資源後,按滑鼠右鍵 build sequence from clip,就可以產生一個新的sequence
    2. 可以直接將Project面版中的資源向右拖到TimeLine中以建立一個sequence
    3. 在Sequence(序列)中刪除時,可以按Delete。刪除的部分就會留空。
    4. 不想要留空的話,可以使用Shift + Delete,就會將空的時間填補
2018年10月25日 星期四

WinForm下簡單的Binding應用 使用 Listbox 來放置資料物件

說明

本文介紹如何使用Binding的方法將讓使用者可以新增、編輯、刪減資料。

示意圖


Code

  • Binding初始化
    1. Combobox的DataSource是透過 Enum.GetValues取得,透過Linq的投影產生的List
    2. 將Combobox的SelectValue和BindingSource所繫結的類別上的屬性做繫結。要注意 SelectedValue的型別會由ComboBox的ValueMember決定。在我們的範例中,是int
    3. 同上,將Textbox上的Text值與BindingSource做繫結。
    4. 上面的兩個步驟是為了要做到 “當BindingSource所選定的項目有變化時,此變化會立刻反應到 Combobox和TextBox上。相同的,使用者在Combobox和TextBox上做的變更,也會立即反應到BindingSource目前選定的物件上”
    5. 在DataBingings的,可以發現都加上 DataSourceUpdateMode.OnPropertyChanged。這是代表當使用者在Textbox上做了變更時,會立即反應到資料上,而不是等到焦點移開時(Invalidate)

       _Bs.DataSource = typeof(Test);

      //Combobox所使用的列舉
      var items = Enum.GetValues(typeof(DockStyle)).OfType().Select()
      comboBox1.ValueMember = "Item1";
      comboBox1.DisplayMember = "Item2";
      comboBox1.DataSource = items;
      comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;

      //將資料與Listbox Binding
      listBox1.DataSource = _Bs;
      //將combobox的SeletedValue屬性與BindingSource內所選擇的物件Binding
      comboBox1.DataBindings.Add(nameof(ComboBox.SelectedValue), _Bs, nameof(Test.DockValue),false, DataSourceUpdateMode.OnPropertyChanged );
      //將textbox的Text屬性與BindingSource內所選擇的物件Binding
      textBox1.DataBindings.Add(nameof(TextBox.Text), _Bs, nameof(Test.DisplayName), false, DataSourceUpdateMode.OnPropertyChanged);
  • 資料物件
    1. 此資料物件有實作INotifyPropertyChanged,這是為了在使用者從控制項編輯資料時,可以立即告知BindingSource 有資料異動
    2. DockValue屬性存在的原因是為了在繫結到ComboBox時,他的 ValueMember 是int,所以我們要新增一個屬性做轉型的動作
    3. ToString被複寫了,因為將此資料呈現在ListBox上時,預設ListBox會將資料做ToString()取得描述值

    internal class Test: INotifyPropertyChanged
    {
      #region INotifyPropertyChanged   
      [field: NonSerialized]
      public event PropertyChangedEventHandler PropertyChanged;
      void OnPropertyChanged([CallerMemberName] string strName = "")
      {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(strName));
      }
      #endregion

      DockStyle _Dock =  DockStyle.None;
      public DockStyle Dock
      {
        get { return _Dock; }
        set
        {
          if (_Dock != value)
          {
            _Dock = value;
            OnPropertyChanged();
          }
        }
      }

      public int DockValue
      {
        get { return (int) Dock; }
        set
        {
          if ((int)Dock != value)
          {
            Dock =(DockStyle) value;
            OnPropertyChanged();
          }
        }
      }

      string _DisplayName = string.Empty;
      public string DisplayName
      {
        get { return _DisplayName; }
        set
        {
          if (_DisplayName != value)
          {
            _DisplayName = value;
            OnPropertyChanged();
          }
        }
      }

      public override string ToString()
      {
        return $"{Dock} - {DisplayName}";
      }
    }
2018年10月24日 星期三

Reactive 之 Observable序列的產生方式

  • Cold Observable
    意指在 Subscribe 後,序列才開始產生,沒有Subscribe 就不會產生。要一個Subscribe訂閱到的都會是一個獨立的序列,不會共用。
    • Range(1,10)
      產生一個1到10的序列,依序發送
    • Timer(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(1))
      使用Timer,在5秒後開始發送,之後每1秒送一個
    • IList.ToObservable()
      直接將一個List的資料轉型成Observable
  • Hot Observable
    意指不論是否有 Subscribe,序列都一直在產生,而且可以多個Subscribe同時訂閱此序列
    • Interval(TimeSpan.FromSeconds(1))
      每一秒產生一筆資料
  • 使用Windows事件
    • FromEventPattern(frm, “MouseMove”)
      使用frm的MouseMove事件來產生序列
2018年10月19日 星期五

dotTrace 說明文件心得 (一)

markdown 本篇記錄我閱讀網頁;https://www.jetbrains.com/help/profiler/ 後的心得 ### Profiling的步驟 1. 建構一個Profiling設定並執行它 2. 使用SnapShot來Dump特定時間點的狀態 3. 分析Dump下來的結果,找出使程式的瓶頸 4. 修改應用程式 5. 再度執行步驟2並與上次的結果比較 ### Profiling的方法 ### Performance Profiling使用時機 1. 分析整個應用程式的效能 2. 找出程式中最慢的部分 3. 在特定方法中尋找瓶頸 ### Timeline Profiling使用時機 1. 找出應用程式的瓶頸 2. 找出造成UI無回應的原因 3. 找出過度IO或是GC的呼叫 4. 分析多執從緒所引入的鎖定、工作分配等。 ### Performance vs Timeline Profiling Performance 可以用來觀察方法被呼叫的頻率、所用的時間,找出應用程式中秏費最多的方法。 但無法明確告知在特定時間下的資源使用狀況。 Timeline 可以用來觀察每一個時間點下的資源使用狀況,該時間點下正在執行的方法。 但不易統計一段時間的方法呼叫頻率、所用時間。 ### Performance Profiling 取資料的方式 1. Sampling 間隔的取,對系統的影響小,取一次資料最少要 5~11 ms 2. Tracing 從CLR中接收方法開始及結束的事件來做取資料 3. Line-by-Line 記錄每個狀態,不過要有.pdb才有辦法。不然就跟Tracking一樣 第一次時建議使用Sampling ### Performance Profiling 統計時間的方式 1. RealTime (performance counter) 方法執行的完整時間,但與方法2相比較不準 2. RealTime (CPU instruction) 同1,但是透過特定API取得,所以較準 3. Thread Time 只記錄Thread有在工作的時間,若是進入Sleep等就不會記錄 4. Thread Cycle Time 用2相同的API去取得Thread有在工作的時間,較方法3來得準。 由於方法3,4會比方法1,2慢很多,所以建議使用方法1,2。 由於方法2較準,所以可以用方法2就用方法2。
2018年10月18日 星期四

統計文字方法 心得

在網路上看到這篇文章
http://www.nimaara.com/2017/07/01/practical-parallelization-with-map-reduce-in-c
它主要是在講怎麼樣快速的統計資料庫中文字出現的頻率。
為了做到加速,它採用了MutliThread的方式。
由於 .net 4 後新增了 PLinq 及Parallel,平行這件事變得更簡單了,但是要如何找出最好的效能,而效能不能好,可以如何觀察是可以從這邊文章學習的地方。
總結來說,這篇文章有趣的地方有

  1. 介紹了效能分析工具,文中提的有 
    1. dotTrace Profiler, 
    2. Visual Studio Performance Profiling
    3. ANTS Performance Profiler
    4. Concurrency Visualizer extension for Visual Studio
    5. CodeTrack
  2. PLinq就透過 AsParallel()來呼叫
  3. PLinq中分資料執行的幾種方式
    1. Chunk partitioning (動態)
    2. Range partitioning (靜態)
    3. Hash partitioning (靜態)
    4. Striped partitioning
  4. PLinq在使用時,可以多次呼叫AsParallel,就是平行處理後再平行處理
  5. PLinq透過Aggregate方法,可以將多個平行在最後時統整成一個
  6. PLinq中,透過ForAll執行一個方法,在方法中透過有同步處理的資料結構來完成,如ConcurrentDictionary
  7. 在讀取資料中,透過BlockingCollection來進行同步。再將此集合內的資料AsParallel出去處理
  8. 不用PLinq改用Parallel去執行
  9. PLinq和Parallel的設定不同的地方在
    1. PLinq設計成一開始就要提供指定的Thread來做平行的工作
    2. Parallel用來在Thread有空閒的時候,才拿這些空閒的Thread來做,否則不拿
2018年10月13日 星期六

說說看,打幾分


今天活動的結尾,負責人問了一下負責該次活動的小隊,要給這次活動打幾分。
不知道辦活動的小隊是客氣還是沒有自信,都給了自己很低的分數。
眼看這種情況,若是問其他小隊的人,不知道會不會也受到影響而沒有辦法得到客觀的分數。
此時,負責人用了一個很聰明的辦法

請大家把眼睛閉上,
你覺得這次的活動有九分的舉手…
好,手放下
你覺得這次的活動有八分的舉手…
好,手放下

由於大家都閉上眼睛,因此自己的看法就不會被別人看見,自己也不會受別人影響。負責人就可以從此觀察到較客觀的意見。

學起來。
2018年10月12日 星期五

有儲存參數時會發生的設計錯誤

場景描述

我們設計了一個UI管理器,此UI管理器可以載入不同的子UI。子UI是由不同的服務所提供。第一次使用時,使用者可以新增子UI。新增完畢後,可以儲存此設定。供下次程式重新啟動時再次回復到上次已增加過子UI的狀態。

問題描述

當程式重開要從設定載入子UI時,由於子UI是由服務而來。若設定中需要的服務不存在時,就會有資料載入失敗的問題,因為資料是要放在UI中,而服務目前不存在。由於我們想要做到資料只是資料,在資料沒有開始運用前,即使服務不在,也不應該影響資料的載入。因此不應該服務不在就無法將資料載入。

問題起因

我們讓子UI是由服務產生,而資料又要放在子UI上。所以造成資料一定要有子UI,而子UI又一定要有服務造成。

問題解法

  1. 讓子UI獨立出來,不屬於服務。這樣就可以在沒有服務的情境下產生子UI。缺點是服務沒有辦法依照自己的需求產生子UI
  2. 讓資料不要透過子UI顯示。如將資料全部轉成字串再以特定符號相連。但這對使用者的體驗不佳

False Sharing

定義

False Sharing指的是在多核心的環境下,由於多個CPU使用到相同的記憶體區塊,造成CPU在執行運算時,為了安全取得共用記憶體時,需要額外進行同步的動作而造成的效能損秏。
上面說的記憶體區塊的意思是指:CPU在取得需要的記憶體時,會連同目標記憶體的鄰近記憶體都會一併取入。
在這種情況下,程式碼中雖然明確指定要特定的記憶體,但Windows核心會"好心"的一同載入,而造成其他CPU要取用的記憶體被拿走而需要等待。

解法

  1. 讓變數在記憶體中的位置不要那麼近,這樣在某個CPU取特定變數時,就不會將其他CPU要用的變數也一併讀入。