[英]Async with Infinite Loop
我有一個需要實時更新的數據集列表。 我想一次處理100個中的10個,然后一個完成后抓住下一個最老的線。 基本上保持這個循環無限的時間。 我對線程世界很陌生,一直在尋找AsyncTask。 有沒有人能指出這個例子? 我用谷歌搜索了一下,但找不到我正在尋找的東西。
如果你知道我的意思,至少使用.Net 4.5異步編程變得非常含糖。
這是一組簡單的例子:
public async void DoAsync()
{
await Task.Run( () =>
{
// Do task!
} );
}
public async Task<string> GetStringAsync()
{
string s = "";
await Task.Run( () =>
{
for(int I = 0; I < 9999999; I++)
{
s += I.ToString();
}
}
return s;
}
http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx
AsyncTask
更適合一次性操作。 對於正在進行的任務,您可以考慮工作線程。
免責聲明:我不認為這是最好的方法,但它應該給你一些想法和東西來閱讀。
public class ThreadingSample : IDisposable
{
private Queue<SomeObject> _processingQueue = new Queue<SomeObject>();
private Thread _worker;
private volatile bool _workerTerminateSignal = false;
private EventWaitHandle _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
public bool HasQueuedItem
{
get
{
lock(_processingQueue)
{
return _processingQueue.Any();
}
}
}
public SomeObject NextQueuedItem
{
get
{
if ( !HasQueuedItem )
return null;
lock(_processingQueue)
{
return _processingQueue.Dequeue();
}
}
}
public void AddItem(SomeObject item)
{
lock(_processingQueue)
{
_processingQueue.Enqueue(item);
}
_waitHandle.Set();
}
public ThreadingSample()
{
_worker = new Thread(ProcessQueue);
_worker.Start();
}
private void ProcessQueue()
{
while(!_workerTerminateSignal)
{
if ( !HasQueuedItem )
{
Console.WriteLine("No items, waiting.");
_waitHandle.WaitOne();
Console.WriteLine("Waking up...");
}
var item = NextQueuedItem;
if (item != null) // Item can be missing if woken up when the worker is being cleaned up and closed.
Console.WriteLine(string.Format("Worker processing item: {0}", item.Data));
}
}
public void Dispose()
{
if (_worker != null)
{
_workerTerminateSignal = true;
_waitHandle.Set();
if ( !_worker.Join( TimeSpan.FromMinutes( 1 ) ) )
{
Console.WriteLine("Worker busy, aborting the thread.");
_worker.Abort();
}
_worker = null;
}
}
public class SomeObject
{
public string Data
{
get;
set;
}
}
}
測試它我使用單元測試啟動它。 您可以將單元測試擴展到適當的測試,以確保按預期執行操作。 在我的情況下,他們是一個很好的初步斷言,以扼殺行為。
[Test]
public void TestThreading()
{
using ( var sample = new ThreadingSample() )
{
sample.AddItem(new ThreadingSample.SomeObject {Data = "First Item"});
sample.AddItem(new ThreadingSample.SomeObject {Data = "Second Item"});
Thread.Sleep(50);
sample.AddItem(new ThreadingSample.SomeObject {Data = "Third Item"});
}
}
測試的相關輸出:
------測試開始:匯編:NHMapping.dll ------
工人處理項目:第一項
工人處理項目:第二項
沒有物品,等待。
起來...
沒有物品,等待。
起來...
工人處理項目:第三項
沒有物品,等待。
起來...
1次傳遞,0次失敗,0次跳過,耗時0.12秒(Ad hoc)。
在這里,您可以看到工作人員進入睡眠狀態,然后醒來處理隊列中的項目。 從技術上講,您可以使用列表,然后從列表中獲取10個項目,然后再從鎖定中釋放它並處理這10個項目,然后再次檢查列表。
當該類被釋放時,它釋放循環,然后等待工作線程在中止之前終止。 在這里,您可能希望檢查是否有任何未完成的項目,並記錄它們將不會被處理,或者將它們保存到文件中以供以后處理。
編輯:我發現了雙重事件的問題...一個更好的實現是使用ManualReset
上EventWaitHandle
private EventWaitHandle _waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
然后在處理處理項目的情況時,重新發送句柄:
var item = NextQueuedItem;
if (item != null) // Item can be missing if woken up when the worker is being cleaned up and closed.
{
Console.WriteLine(string.Format("Worker processing item: {0}", item.Data));
_waitHandle.Reset();
}
這會產生更好的測試結果:
------測試開始:匯編:NHMapping.dll ------
工人處理項目:第一項
工人處理項目:第二項
沒有物品,等待。
起來...
工人處理項目:第三項
沒有物品,等待。
起來...
1次傳遞,0次失敗,0次跳過,耗時0.13秒(Ad hoc)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.