[英]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.