Posts
Visual Studio 15 Preview - Open folder
Visual Studio 15 Preview 開始支援用目錄的方式開啟。
使用上只要點選 [File | Open | Folder…] 主選單選項,選取要載入的目錄即可。
{% img /images/posts/VS15PreviewOpenFolder/1.png %}
{% img /images/posts/VS15PreviewOpenFolder/2.png %}
read morePosts
Visual Studio 15 Preview - Naming style
Visual Studio 15 Preview 開始支援命名規則的檢查。
使用時可開啟選項視窗,切換到 [Text Editor | C# | Code Style | Naming] 頁面,點選右側頁面的 “+” 按鈕,加入新的命名規則。
{% img /images/posts/VS15PreviewNamingStyle/1.png %}
在彈出的命名規則對話框中,我們要先為這個命名規則取個名字,接著點選符號規格後的 “+” 按鈕,設定命名規則要套的範圍。
{% img /images/posts/VS15PreviewNamingStyle/2.png %}
符號規格對話框這邊,我們一樣要給符號規格命名,然後決定命名規則套用的範圍。像是這邊筆者想要對所有方法生效,在符號種類這邊就要選取 method,存取範圍則全部選取。
{% img /images/posts/VS15PreviewNamingStyle/3.png %}
符號規則訂定後,接著要訂定命名樣式,命名樣式這邊一樣要為它命名,然後設定他的前置詞,後置詞,分隔字元,大小寫。像是這邊筆者想要讓所有的方法都用 Pascal 命名,所以這邊將設定調為 Pascal 大小寫名稱。
{% img /images/posts/VS15PreviewNamingStyle/4.png %}
最後要設定的是命名規則的嚴重程度,這邊視個人需要下去調整即可,看覺得是 None,Info,Warning,Error 哪個層級都可。
{% img /images/posts/VS15PreviewNamingStyle/5.png %}
設定好後在撰寫程式時 Visual Studio 就會依照制定的命名規則下去檢查。
{% img /images/posts/VS15PreviewNamingStyle/6.png %}
read morePosts
Opserver - Stack Exchange's Monitoring System
Opserver 是 Stack Exchange 開發的監控系統,能夠針對以下系統進行監控:
Servers/Switches & anything supported by Bosun, Orion, or direct WMI monitoring SQL Clusters & Single Instances Redis Elasticsearch Exception Logs (from StackExchange.Exceptional) HAproxy PagerDuty CloudFlare DNS 安裝上只需要從 Github 將 Opserver 抓下來,開啟 Opserver 專案,然後設定其對應的 Config,並將之部署到網站伺服器運行即可。
Opserver 的 Config 設定放置於 /Opserver/Config/ 下,參閱放置在裡面的 example 檔設定即可。需先針對 Opserver/Config/SecuritySettings.config 下去設定,設定網站的安全性,再來才是要監控的系統對應的設定。如果設定後本地運行無法看到效果,可將 IISExpress 停掉後重跑看看。
{% img /images/posts/Opserver/1.png %}
{% img /images/posts/Opserver/2.png %}
{% img /images/posts/Opserver/3.png %}
{% img /images/posts/Opserver/4.png %}
{% img /images/posts/Opserver/5.png %}
read morePosts
UniqueIdGenerator - C# implementation of Twitter's Snowflake
UniqueIdGenerator 是 Twitter Snowflake ID 的 C# 實作。
產生的 ID 預設有 64 bit,就一個 long 的大小,由 41 bit 為 Timestamp,10 bit 為 Generator id,13 bit 的 Sequence 所組成。
使用上要先透過 NuGet 安裝 UniqueIdGenerator 套件。
{% img /images/posts/UniqueIdGenerator/1.png %}
{% img /images/posts/UniqueIdGenerator/2.png %}
接著引用 UniqueIdGenerator.Net 命名空間,帶入 Generator id 與 EPoch 建立 Generator,然後調用 Next() 取得文字型態的 ID,或是透過 NextLong() 取得數值型態的 ID 即可。
... using UniqueIdGenerator.Net; ... var generatorID = GetGeneratorID(); var epoch = GetEPoch(); var generator = new Generator(generatorID, epoch); .
read morePosts
IdGen - Twitter Snowflake-alike ID generator for .Net
IdGen 是 ID 產生器套件,可用以產生 Twitter Snowflake-alike 的 ID,具備彈性,支援許多不同的建構方式,支援調整 ID 的結構。
IdGen 產生的 ID 預設有 64 bit,就一個 long 的大小, 由 1 bit 的正負符號, 41 bit 的 Timestamp, 10 bit 的 Generator id, 12 bit 的 Sequence 所組成。
{% img /images/posts/IdGen/1.png %}
使用上要先透過 NuGet 安裝 IdGen 套件。
{% img /images/posts/IdGen/2.png %}
{% img /images/posts/IdGen/3.png %}
接著引用 IdGen 命名空間,建立 IdGenerator,然後調用 CreateId() 取得單一 ID,或是調用 Take() 取得多個 ID 即可。
using IdGen; ... var generator = GetIdGenerator(); var id = generator.
read morePosts
Disruptor - WorkerPool
Disruptor 的 EventHandler,Consumer 間會相互合作,會依序消費收到所有的資料。但有的場景我們可能會需要多個 Consumer 分攤處理收到的資料,這時可以採用 WorkerHandler。
像是我們可以撰寫下面這樣的 WorkerHandler:
... public class Data { public string Value { get; set; } } public class DataWorkHandler : IWorkHandler<Data > { public string Name { get; private set; } public DataWorkHandler( string name) { this.Name = name; } public void OnEvent( Data @event) { Console.WriteLine( "Thread = {0}, Handler = {1}, Value = {2} ", Thread.CurrentThread.ManagedThreadId.ToString(), this.Name, @event.Value); } } ... 這邊建造多個 WorkerHandler,帶入 Disruptor 的 HandleEventsWithWorkerPool 方法。
read morePosts
T4 Template - T4Enum 1.0
.NET 列舉的很多操作都會有難以避免的 Boxing/UnBoxing,像是要取得特定列舉值的列舉名,取得所有的列舉名,取得所有的列舉值,取得列舉值的 Attribute,都無法避免 Boxing/UnBoxing 的發生。
{% img /images/posts/T4Enum/1.png %}
這邊筆者嘗試用 T4 來解這問題,用 T4 範本可以遍尋專案內的所有列舉,產生對應的輔助類別與擴充方法,藉此避開列舉操作的 Boxing/UnBoxing 問題。
程式可至 NuGet Gallery | LevelUp.T4Enum 1.0.0 這邊抓取。
實際使用會像是下面這樣:
using System; using T4Enum; using T4Enum.Extensions; namespace ConsoleApplication7 { enum Permission { Function1, Function2, Function3 } class Program { static void Main(string[] args) { Console.WriteLine(Enums.Permission.Function1.Name); Console.WriteLine((int)Enums.Permission.Function1.Value); Console.WriteLine(Enums.Permission[Permission.Function2].Name); Console.WriteLine((int)Enums.Permission[Permission.Function2].Value); Console.WriteLine(Enums.Permission.GetName(Permission.Function3)); Console.WriteLine(Permission.Function3.GetName()); foreach (var item in Enums.Permission) { Console.WriteLine(item.Name); Console.WriteLine((int)item.Value); } foreach (var name in Enums.Permission.GetNames()) { Console.
read morePosts
T4 Template - JsResource.tt
在撰寫 ASP.NET 時,.NET 程式部分可用 Resource 去做多語的部分,JavaScript 這邊雖然也有 L10N 的解決方案,但是若走不同的解決方案,難以避免有些詞彙會重複定義。
這邊筆者嘗試使用 T4 來解決這樣的問題。
<#@ template language="C#" debug="false" hostspecific="true"#> <#@ assembly name="System.Windows.Forms" #> <#@ assembly name="System.Core" #> <#@ assembly name="System.Xml" #> <#@ assembly name="EnvDTE" #> <#@ assembly name="Microsoft.VisualStudio.OLE.Interop" #> <#@ assembly name="Microsoft.VisualStudio.Shell" #> <#@ assembly name="Microsoft.VisualStudio.Shell.Interop" #> <#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #> <#@ import namespace="System.Resources" #> <#@ import namespace="System.Diagnostics" #> <#@ import namespace="System.Collections" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.
read morePosts
Disruptor - Consumer's WaitStrategy
Disruptor 內建幾種等待策略,可用以設定消費者怎樣等待生產者的資料。在實務上,我們可能要針對不同的產品特性下去調整等待的策略。
預設的等待策略為 BlockingWaitStrategy,內部是用 Lock 與條件變數下去實作,用於對低延遲與高產能不是那麼重視的情境。雖然產能不高,但能確保在不同的環境下有一致的性能表現。
這邊筆者做了簡單的測試,在 Unicast 1p-1c 的狀況下瘋狂寫入,每秒約處理 145 筆資料。
{% img /images/posts/DisruptorWaitStrategy/1.png %}
如果讓 Producer 不要那麼頻繁的產生資料,那會看到消費者在等待的同時 CPU 會忙於等待。
{% img /images/posts/DisruptorWaitStrategy/2.png %}
SleepingWaitStrategy 策略則是用迴圈下去睡眠等待。可以看到這邊的實驗,每秒處理可達到約 18xxxx 筆資料。
{% img /images/posts/DisruptorWaitStrategy/3.png %}
且等待生產者資料時 CPU 耗費也不高。
{% img /images/posts/DisruptorWaitStrategy/4.png %}
BusySpinWaitStrategy 策略套到同樣的實驗,每秒處理約 144 筆資料。
{% img /images/posts/DisruptorWaitStrategy/5.png %}
等待資料時 CPU 也是飆高狀態。
{% img /images/posts/DisruptorWaitStrategy/6.png %}
YieldingWaitStrategy 策略套到同樣的實驗,每秒處理約 24xxxx 筆資料.
{% img /images/posts/DisruptorWaitStrategy/7.png %}
等待資料時 CPU 依舊飆高。
{% img /images/posts/DisruptorWaitStrategy/8.png %}
read morePosts
WinDBG - Check memory leak with dumpheap
要檢查程式的 Memory leak,我們可以在程式物件應該被釋放時抓取 Dump 檔案,像是程式運行後隔一陣子,理論上 GC 應該已經將物件回收時抓取,抓取後就可以用 WinDBG 進一步的分析。
分析時將 WinDBG 開啟,點選 [File | Symbol File Path…] 。
{% img /images/posts/CheckMemoryLeakWithWinDBG/1.png %}
將 Symbol Server 的位置加入(SRVc:\symbolshttp://msdl.microsoft.com/download/symbols) 。
{% img /images/posts/CheckMemoryLeakWithWinDBG/2.png %}
接著點選 [File | Open Crash Dump…] 載入 Dump File ( 直接將 Dump 檔拖曳至 WinDBG 也可 )。
{% img /images/posts/CheckMemoryLeakWithWinDBG/3.png %}
{% img /images/posts/CheckMemoryLeakWithWinDBG/4.png %}
接著輸入命令 .loadby sos clr,將 SOS 偵錯擴充功能載入。
{% img /images/posts/CheckMemoryLeakWithWinDBG/5.png %}
再輸入命令 !dumpheap –stat 將 heap state dump 出來。
read more