简体   繁体   中英

ThreadPool or Task.Factory

I have windows service that can get requests, I want to handle in each request in separated thread.

I want to limit also the number of the threads, ie maximum 5 threads.

And i want to wait for all threads before i'm close the application,

What is the best way to do that?

What I'm tried:

 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?

In this way i can limit the number of the theads?

Or

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);

There is another way to implement that?

Task.WaitAll();//Not waiting actually for all threads, why? you have to the following

 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);

I think that you should make the differences between Task and thread

Task are not threads Task is just a promise of result in the future and your code can execute on only one thread even if you have many tasks scheduled

Thread is a low-level concept if you start a thread you know that it will be a separate thread I think you first implentation is well enough to be sure that all your code is executed but you have to use Task.Run instead of Task.Factory.StartNew

Both approaches should work, neither is a guarantee that each operation will run in a different thread (and that is a good thing). Controlling the maximun number of threads is another thing...

You can set the maximun number of threads of the ThreadPool with SetMaxThreads . Remember that this change is global, you only have one ThreadPool .

The default TaskScheduler will use the thread pool (except in some particular situations where it can run the taks inline on the same thread that is calling them), so changing the parameters of the ThreadPool will also affect the Tasks .

Now, notice I said default TaskScheduler . You can roll your own, which will give you more control over how the tasks will run. It is not advised to create a custom TaskScheduler (unless you really need it and you know what you are doing).


For the embedded question:

Task.WaitAll();//Not waiting actually for all threads, why?

To correctly call Task.WaitAll you need to pass the tasks you want to wait for as parameters. There is no way to wait for all currently existing tasks implicitly, you need to tell it what tasks you want to wait for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM