亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

async Func

async Func

C#
飲歌長嘯 2023-12-17 10:49:07
方法內的 3 個調用有什么區別WhatDifferences?這是測試代碼:async Task WhatDifferences(Context context){    await ActionAsync(context, async x => await IsOddAsync(x).ConfigureAwait(false));    await ActionAsync(context, x => IsOddAsync(x));    await ActionAsync(context, IsOddAsync);}async Task<T> ActionAsync<T>(Context context, Func<Context, Task<T>> action){    return await action(context).ConfigureAwait(false);}async Task<bool> IsOddAsync(Context context){    return await Task.Run(() => context.Count++ % 2 == 1).ConfigureAwait(false);}class Context{    public int Count { get; set; }}我正在嘗試決定在我的代碼庫中使用哪一個,并且根據我的知識,所有 3 個的行為都是相同的。問題與不同傳遞異步委托的方法簽名是什么?如果我表現得更有邏輯,你可能會知道我的擔憂async Task<T> ActionAsync<T>(Context context, Func<Context, Task<T>> action){    using (var transaction = new TransactionScope())    {        //do some async logic before action        var result = await action(context).ConfigureAwait(false);        //do other async validation logic after action        return result;    }}
查看完整描述

2 回答

?
慕婉清6462132

TA貢獻1804條經驗 獲得超2個贊

我正在嘗試決定在我的代碼庫中使用哪一個,并且根據我的知識,所有 3 個的行為都是相同的。

在這個具體例子中,這基本上是正確的。

此創建一個引用?IsOddAsync?方法的委托:

await?ActionAsync(context,?IsOddAsync);

這個為 lambda 表達式創建一個方法,委托引用編譯器生成的方法:

await?ActionAsync(context,?x?=>?IsOddAsync(x));

這個函數的作用相同,但對于異步 lambda,因此編譯器生成的方法也有一個?async?狀態機:

await?ActionAsync(context,?async?x?=>?await?IsOddAsync(x).ConfigureAwait(false));

一般來說,你的問題可以歸結為兩個問題:

  1. 我應該使用方法組而不是 lambda 嗎?是的你應該。這樣做沒有任何缺點,而且效率更高、代碼更短,而且對可維護性沒有任何影響。

  2. 我應該刪除async/await還是保留關鍵字?這個更加細致。

在這種特殊情況下省略?沒問題,因為?lambda 所做的只是調用單個方法并傳遞其參數。在調用?之前或之后,lambda 不可能拋出異常。async?asyncIsOddAsync

但是,如果您的 lambda 更復雜 - 在將?x?傳遞給?IsOddAsync?之前對其進行操作,或者對結果進行操作,或者使用using?塊,那么您需要保留?async/await?關鍵字以獲得最大的可維護性。


查看完整回答
反對 回復 2023-12-17
?
鴻蒙傳說

TA貢獻1865條經驗 獲得超7個贊

await與返回Task

和...之間的不同:

await?ActionAsync(context,?async?x?=>?await?IsOddAsync(x).ConfigureAwait(false));
await?ActionAsync(context,?x?=>?IsOddAsync(x));

在某些情況下,您不需要?await(當然也不需要?async

執行異步操作的方法不需要使用await,如果:

  • 方法內部只有一次異步調用

  • 異步調用在方法的最后

  • 沒有必要捕獲/處理任務中可能發生的異常

在這種情況下,您可以中間返回Task。

請注意,行為上存在細微差別 - 取決于IsOddAsync的實現:

重要提示:返回任務而不是等待它,會更改方法的異常行為,因為它不會在啟動任務的方法中拋出異常,而是在等待任務的方法中拋出異常。

正如 Gabriel Luci 所指出的,在當前實現的?IsOddAsync(一次調用和一次?await)中,行為沒有差異。

x => IsOddAsync(x)IsOddAsync

和...之間的不同

await?ActionAsync(context,?x?=>?IsOddAsync(x));
await?ActionAsync(context,?IsOddAsync);

在第一個中,您將使用參數創建一個匿名 (lambda) 方法x。由于?IsOddAsync?也有一個參數(類型相同),因此不需要 lambda 方法。

請注意,如果?IsOddAsync?有其他參數,例如,您需要 lambda和第二個參數,那么你需要 lambda。示例:

await?ActionAsync(context,?x?=>?IsOddAsync(x,?"mySecondParameter"));

在這種情況下,除了內部拋出異常時的調用堆棧之外,行為沒有任何區別。


查看完整回答
反對 回復 2023-12-17
  • 2 回答
  • 0 關注
  • 147 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號