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

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

如何在異步 C# 任務中使用 yield

如何在異步 C# 任務中使用 yield

C#
呼啦一陣風 2021-11-28 19:31:56
我正在嘗試使用 yield 并返回在異步任務中將 X 轉換為 Y 的結果。但是,我在選擇時遇到錯誤。錯誤是:錯誤 CS1942 select 子句中的表達式類型不正確。調用“Select”時類型推斷失敗。public async Task<Result<dynamic>> GetYAsync(IEnumerable<X> infos)    {        return Task.WhenAll(from info in infos.ToArray() select async ()=>        {            yield return await new Y(info.Id, "Start");        });    }
查看完整描述

2 回答

?
小唯快跑啊

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

簡短回答:您不能使用異步 yield 語句。


但在大多數情況下,您不需要。使用LINQ您可以在將所有任務傳遞到Task.WaitAll. 我簡化了您的示例以返回IEnumerable<int>,但這適用于每種類型。


public class Program

{

   public static Task<int> X(int x) 

   {

       return Task.FromResult(x);

   }

    

   public static async Task<IEnumerable<int>> GetYAsync(IEnumerable<int> infos)

   {

       var res = await Task.WhenAll(infos.Select(info => X(info)));

       return res;

   }

    

   public static async void Main()

   {

       var test = await GetYAsync(new [] {1, 2, 3});

       Console.WriteLine(test);

   }

}

您的示例還有另一個錯誤await new Y(...),構造函數不能是異步的,因此我將其替換為異步函數。(正如評論中所暗示的,在技術上可以創建自定義的可等待類型并使用 來創建這種類型new,盡管很少使用),


上面的示例infos.Select用于創建掛起任務列表,通過調用函數返回X。然后將等待并返回此任務列表。


這workaround應該適合大多數情況。.Net 不支持真正的異步迭代器,例如在 JavaScript 中。


更新:目前建議將此功能作為語言建議:Async Streams。所以也許我們將來會看到這一點。


更新:如果您需要異步迭代器,目前有幾個選項可用:

  1. Reactive Stream,RX.Net,它為您提供基于事件的異步可觀察流。

  2. 有異步迭代器或異步可枚舉的實現AsyncEnumerable或 .Net Async Enumerable


查看完整回答
反對 回復 2021-11-28
?
慕村9548890

TA貢獻1884條經驗 獲得超4個贊

你不。2019 年的某個時間點,C# 8 提供了異步枚舉支持(并且通過 yield 來實現可枚舉)。所以,現在的答案很簡單,你沒有。

您收到錯誤的原因是您也無法返回結果。產量(回報)特定于實現枚舉。您的方法簽名不匹配。


查看完整回答
反對 回復 2021-11-28
  • 2 回答
  • 0 關注
  • 262 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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