ThreadPool或Task.Factory

时间:2017-02-23 08:39:20

标签: c# multithreading

我有可以获取请求的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);

还有另一种方法可以实现吗?

2 个答案:

答案 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,您需要将要等待的任务作为参数传递。无法隐式等待所有当前存在的任务,您需要告诉它您要等待的任务。