我有可以获取请求的Windows服务,我想在分离的线程中处理每个请求。
我想限制线程数,即最多5个线程。
我想在关闭应用程序之前等待所有线程,
最好的方法是什么?
我的尝试:
for (int i = 0; i < 10; i++)
{
var i1 = i;
Task.Factory.StartNew(() => RequestHandle(i1.ToString())).ContinueWith(t => Console.WriteLine("Done"));
}
Task.WaitAll();//Not waiting actually for all threads, why?
这样我可以限制theads的数量吗?
或者
var events = new ManualResetEvent[10];
ThreadPool.SetMaxThreads(5, 5);
for (int i = 0; i < 10; i++)
{
var i1 = i;
ThreadPool.QueueUserWorkItem(x =>
{
Test(i1.ToString());
events[i1].Set();
});
}
WaitHandle.WaitAll(events);
还有另一种方法可以实现吗?
答案 0 :(得分:1)
Task.WaitAll();//Not waiting actually for all threads, why?
你需要以下
List<Task> tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
var i1 = i;
tasks.Add(Task.Factory.StartNew(() => RequestHandle(i1.ToString())).ContinueWith(t => Console.WriteLine("Done")));
}
Task.WaitAll(tasks);
我认为你应该在Task和thread之间做出区别
任务不是线程任务只是未来结果的承诺,即使您安排了许多任务,您的代码也只能在一个线程上执行
线程是一个低级概念,如果你启动一个线程,你知道它将是一个单独的线程
我认为您第一次实施已足够确保所有代码都已执行但您必须使用Task.Run
而不是Task.Factory.StartNew
答案 1 :(得分:0)
两种方法都应该有效,也不能保证每个操作都在不同的线程中运行(这是一件好事)。控制最大线程数是另一回事......
您可以使用SetMaxThreads
设置ThreadPool
的最大线程数。请记住,此更改是全局更改,您只有一个ThreadPool
。
默认的TaskScheduler
将使用线程池(在某些特殊情况下,它可以在调用它们的同一线程上运行内联),因此更改ThreadPool
的参数将也会影响Tasks
。
现在,请注意我说默认TaskScheduler
。您可以自己滚动,这将使您可以更好地控制任务的运行方式。建议不要创建自定义TaskScheduler
(除非您确实需要它,并且您知道自己在做什么)。
对于嵌入式问题:
Task.WaitAll();//Not waiting actually for all threads, why?
要正确调用Task.WaitAll
,您需要将要等待的任务作为参数传递。无法隐式等待所有当前存在的任务,您需要告诉它您要等待的任务。