-1
我想創建一個容器,每次我想要它的項目(迭代),它返回項目給我延遲。 真的我想要實現多種延遲(返回每個項目+延遲返回一些項目後延遲與計時器+延遲)。實現IEnumerable包含異步/等待任務
但我在下面的例子中簡化了這個想法。 以下代碼有效,但當我使用await Task.Delay(...)
時出現問題。我在代碼中描述它(請閱讀評論)。
問題:
- 有一個
GetEnumerator
方法來實現它的方式防止封鎖,迭代MyContainer object
線程的? - 你有什麼有趣的方式來實現這個想法(任何有趣的解決方案)? :)
我認爲,很明顯,我想隱藏在
IEnumerable<T>
嵌入延遲機制。我不會在
List<int>
上做出簡單的foreach
包括延遲我的高級別課程。我想用一個嵌入延遲機制做一個容器,最後只需在
MyContainer
之上使用foreach
而沒有任何延遲(就像波紋管測試一樣)。
class MyContainer : IEnumerable<int>
{
private readonly int _sec;
private readonly List<int> _items;
public MyContainer(List<int> items, int sec)
{
this._sec = sec;
this._items = items;
}
public IEnumerator<int> GetEnumerator()
{
for (int i = 0; i < _items.Count(); ++i)
{
//-----------------------------------------------------------------
// It works but block caller thread (E.g. block UI Thread)
Thread.Sleep(Sec*1000);
//-----------------------------------------------------------------
//Problem line:
//Because return type of current method should be async Task<...>
//And it seems «yield» has problem with Task methods
//await Task.Delay(_sec*1000); // <<< Error line
//-----------------------------------------------------------------
yield return _items[i];
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
測試上面的代碼與Thread.Sleep
(無await Task.Delay
):
var myCnt=new MyContainer(new List<int>() {10,20,30,40,50}, 2);
var sw=new Stopwatch();
sw.Start();
foreach (var item in myCnt)
{
Trace.WriteLine(sw.Elapsed);
}
sw.Stop();
// Result:
// 00:00:02.0014343
// 00:00:04.0034690
// 00:00:06.0045362
// 00:00:08.0056571
// 00:00:10.0067891
目前尚不清楚你在做什麼。你希望你的迭代器包含一個延遲,但是你不想'foreach'被延遲?這聽起來可能是你需要的延遲/定時器應該在堆棧的不同部分實現。 –
順便說一句,如果您使用'IAsyncEnumerable'的實現,則更容易混合異步/等待和枚舉類型,例如:https://github.com/tyrotoxin/AsyncEnumerable –
@NateBarbettini,您的'IAsyncEnumerable'鏈接很有趣!你可以在這裏以你的評論爲例作爲答案嗎?如果他們想混合IEnumerable '和'像我這樣的任務,我認爲它將在這個問題頁面的未來幫助其他人。 鏈接: _幫助(a)創建一個元素提供程序,其中由於依賴於其他異步事件(例如,生成元素)可能需要很長時間。等待句柄,網絡流), (b)一個消費者在它們準備就緒時立即處理這些元素而不阻塞線程(而是在工作線程上調度處理)._ –
RAM