Sai*_*ash 8 c# long-running-processes task-parallel-library
我有一个需要从数据库中选择作业并需要处理它的Windows服务.
在这里,每项工作都是一个扫描过程,大约需要10分钟才能完成.
我是任务并行库的新手.我已经按以下方式实现了示例逻辑:
Queue queue = new Queue();
for (int i = 0; i < 10000; i++)
{
queue.Enqueue(i);
}
for (int i = 0; i < 100; i++)
{
Task.Factory.StartNew((Object data ) =>
{
var Objdata = (Queue)data;
Console.WriteLine(Objdata.Dequeue());
Console.WriteLine(
"The current thread is " + Thread.CurrentThread.ManagedThreadId);
}, queue, TaskCreationOptions.LongRunning);
}
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)
但是,这创造了很多线程.由于循环重复100次,因此创建了100个线程.
创建那么多并行线程是正确的方法吗?
有没有办法将线程数限制为10(并发级别)?
分配 new 时要记住的一个重要因素Threads是操作系统必须分配许多逻辑实体才能运行当前线程:
除此之外,Threads可能运行的并发数量取决于您的机器正在打包的核心数量,并且创建大于您的机器拥有的核心数量的线程数量将开始导致Context Switching,从长远来看,这可能会减慢速度你的工作下降了。
经过漫长的介绍,接下来是好东西。我们真正想要做的是限制运行的线程数量并尽可能地重用它们。
对于这种工作,我会选择基于模式的TPL 数据流Producer-Consumer。举一个小例子来说明可以做什么:
// a BufferBlock is an equivalent of a ConcurrentQueue to buffer your objects
var bufferBlock = new BufferBlock<object>();
// An ActionBlock to process each object and do something with it
var actionBlock = new ActionBlock<object>(obj =>
{
// Do stuff with the objects from the bufferblock
});
bufferBlock.LinkTo(actionBlock);
bufferBlock.Completion.ContinueWith(t => actionBlock.Complete());
Run Code Online (Sandbox Code Playgroud)
您可以传递每个Blocka ExecutionDataflowBlockOptions,这可能会限制Bounded Capacity(BufferBlock 内的对象数量),并MaxDegreeOfParallelism告诉块您可能想要的最大并发数。
这里有一个很好的例子可以帮助您入门。
| 归档时间: |
|
| 查看次数: |
692 次 |
| 最近记录: |