類庫使用ConfigureAwait.Fody配置全局ConfigureAwait (false)取消異步上下文切換提高性能(FodyWeavers.xml文件)

類庫使用ConfigureAwait.Fody配置全局ConfigureAwait (false)取消異步上下文切換 - 唐 森 - 博客園 

https://www.cnblogs.com/townsend/p/13748954.html

 

在.net中(包括.net core和.net framework)異步任務默認的會帶有一個上下文關聯的一個狀態機,也就是配置的ConfigureAwait爲ture,微軟官方文檔解釋爲:嘗試將延續任務封送回原始上下文
譬如一個異步方法:

async Task MethodWithContextAsync () {
    await Task.Delay (TimeSpan.FromSeconds (1));
    // 默認會獲取一個上下文(上下文會獲取一個調度者,沒有則從線程池中獲取),並在該上下文中回調,
}

默認的方法等同於

async Task MethodWithContextAsync () {
    await Task.Delay (TimeSpan.FromSeconds (1)).ConfigureAwait(true);
    // 等同與沒加.ConfigureAwait方法
}

如果只是在類庫中使用異步方法,則可以加.ConfigureAwait(false);

async Task MethodWithoutContextAsync () {
    await Task.Delay (TimeSpan.FromSeconds (1)).ConfigureAwait(false);
    // 去掉掉任務的上下文,沒有了上下文對象的開銷,也就能提高性能
}

如果每一個異步方法調用都加上ConfigureAwait(false)則改動比較大,這時候就可以利用ConfigureAwait.Fody來做全局配置,
編譯後的就會在項目裏的每一個異步調用後面加上ConfigureAwait(false),相當於AOP靜態織入。

添加nuget包:

PM> Install-Package Fody
PM> Install-Package ConfigureAwait.Fody

然後在VS項目中右鍵生成,會看到多了一個FodyWeavers.xml文件

默認是沒有設置ConfigureAwait(false),需要在FodyWeavers.xml的ConfigureAwait節點添加 ContinueOnCapturedContext="false"

<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
  <ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

使用ILSpy反編譯下程序集生成的dll,可以看到ConfigureAwait.Fody已經在編譯期間自動在異步方法調用後面加上了.ConfigureAwait(continueOnCapturedContext: false)

ConfigureAwait相關參考資料:
https://www.cnblogs.com/xiaoxiaotank/p/13529413.html
https://www.cnblogs.com/AlienXu/archive/2019/07/12/11177434.html
https://github.com/Fody/ConfigureAwait

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章