類庫使用ConfigureAwait.Fody配置全局ConfigureAwait (false)取消異步上下文切換


在.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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM