我有一个需要实时更新的数据集列表。我想每次处理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'。 –