我有一個需要實時更新的數據集列表。我想每次處理100個以上的10個,然後一旦完成,就抓住下一個最老的線。基本上保持這個循環持續無限的時間。我對線程的世界很陌生,並且一直在AsyncTask中探索。有沒有人可以指點我的例子?我GOOGLE了很多,但無法找到我正在尋找的東西。與無限循環異步
與無限循環異步
回答
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個項目。
當類配置它釋放則循環等待片刻工作線程中止之前終止。在這裏,您可能需要檢查是否有未完成的項目,並記錄它們將不會被處理,或者將它們保存到文件中供以後處理。
編輯:我發現這個問題有雙重事件...更好的實現是使用在EventWaitHandle
private EventWaitHandle _waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
一個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)。
至少在.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
- 1. 從異步無限循環退出
- 2. EventHandler庫與異步,無限循環和全局變量鎖定
- 3. 無限循環,同時在* ngFor與異步管
- 4. 無限循環同步syncadapter
- 5. 與承諾異步循環?
- 6. AngularJS無限循環與$ q
- 7. 與cocos2d的無限循環
- 8. JavaScript異步循環
- 9. JavaScript異步循環
- 10. C++異步循環
- 11. 異步循環iOS
- 12. For循環異步
- 13. 無限循環在JavaScript中異步回調格局
- 14. Android SyncAdapter陷入無限同步循環
- 15. 谷歌日曆同步無限循環
- 16. 在另一個異步循環內的Javascript異步循環
- 17. NodeJs使用異步與循環下載
- 18. 問題與異步jQuery和循環
- 19. RxJava for循環與異步方法?
- 20. 處理與nodejs異步回調循環
- 21. 無限循環?
- 22. 無限循環:
- 23. 無限循環
- 24. 無限循環
- 25. 無限循環
- 26. 無限循環
- 27. 無限循環
- 28. 無限循環
- 29. (?無限)循環
- 30. 無限循環?
第二項和第三項之間的雙重喚醒有點令人感興趣,可能是由於我用每個AddItem調用觸發了'EventWaitHandle'。 –