您好,登錄后才能下訂單哦!
小編給大家分享一下C#中異步迭代IAsyncEnumerable應(yīng)用的實現(xiàn)方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
首先,嘗試寫第一個方法
private void Button_Click(object sender, RoutedEventArgs e) { var dateStart = DateTime.Now; //記錄用時的起始時間 DebugText = string.Empty; List<string> fpList = new List<string>() { "a", "b", "c", "d" }; foreach (var item in MockIO) { var dateEnd = DateTime.Now; var timeSpan = dateEnd - dateStart;//記錄開票用時 DebugText += item + " " + timeSpan.TotalSeconds + "\r\n"; } } /// <summary> /// 批量開票方法 /// </summary> /// <param name="ls"></param> /// <returns></returns> public static IEnumerable<string> MockIO(List<string> ls) { foreach (var item in ls) { Task.Delay(1000).Wait(); yield return item; Debug.WriteLine(Thread.GetCurrentProcessorId()); } }
來看效果
很明顯,發(fā)生了UI阻塞情況。因為我們并未對代碼做任何異步處理。接下來,我們開始嘗試修改。
首先,我們嘗試按照常規(guī)異步方法修改 MockIO 函數(shù),增加 async 關(guān)鍵詞,返回結(jié)果增加 Task, 內(nèi)部對IO操作添加 await。
修改完畢后,編譯并沒有通過,VS對該方法報異常
通過提示信息,我們可以發(fā)現(xiàn),返回值 Task<IEnumerable<string>> 并不是可以迭代的,因為我們采用了 yield 來返回值,所以我們需要一個可以迭代的返回值。
比如改成這樣
但是,這樣一次就返回一組 Task ,沒有用到方便的 yield;
此時,就可以用到 IAsyncEnumerable 來設(shè)計了,IAsyncEnumerable是C# 8.0引入的新特性,在異步迭代中,非常方便。如上述代碼,可以直接修改為
public static async IAsyncEnumerable<string> MockIOAsync(List<string> ls) { foreach (var item in ls) { Task<Task<string>> task = Task<Task<string>>.Factory.StartNew(async () => { await Task.Delay(1000); return item; }); yield return await task.Result; } }
我們再運行調(diào)試,看一下效果
我們可以看到,不僅UI沒有被阻塞,同時,傳回的值也是一個接一個的傳過來的,符合我們的預(yù)期。
擴展:雖然上述步驟我們完成的UI的非阻塞的實現(xiàn),但是我們整個開票用時并沒有節(jié)省。
接下來,我將繼續(xù)修改 MockIOAsync 方法,將實現(xiàn)迭代器內(nèi)部的多線程操作。
修改后的代碼如下
public static async Task<IEnumerable<string>> MockIOPerformanceAsync(List<string> ls) { List<string> lss = new List<string>(); List<Task> tasks = new List<Task>(); foreach (var item in ls) { Task task = new Task(() => { Task.Delay(1000).Wait(); Debug.WriteLine(Thread.GetCurrentProcessorId()); lss.Add(item); }); tasks.Add(task); task.Start(); } foreach (var item in tasks) { await item; } return lss; }
效果展示:
嗯,速度很快,但是排序亂了,因為此方法在遍歷中新建了線程,list 添加并不保證按照迭代器的順序添加。
以上是“C#中異步迭代IAsyncEnumerable應(yīng)用的實現(xiàn)方法”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。