I'm new to all the parallel programming paradigms in .NET and I'd like to know two things:
I have a private async Task RunTask(string task)
method that I need to run as many times as the number of tasks I have.
Inside a private async void button_click(object sender, EventArgs e)
class, I have a List of strings called tasklist
which initializes the tasks I need to run. I'm running the following code:
Thread thread = new Thread(()=> Parallel.ForEach(tasklist, t => RunTask(t)));
thread.Start();
RunOnCompletionOfTasks();
I need to be able to utilize all my CPU cores and run all tasks in the shortest amount of time possible. I figured Parallel.ForEach
was the best way to achieve this but my tasks are also async
because they have functions that require waiting on other methods. My tasks also append one string to a List<string>
object within the class during their execution.
Parallel.ForEach
causes my Windows Form to freeze up so I encapsulated it within a thread. The problem with this is that RunOnComlpetionOfTasks();
runs before my tasks have completed.
What's the most efficient way for me to run all my RunTask
tasks and then run RunOnCompletionOfTasks
upon completion without freezing up the Windows Form?
Please and thank you.
If you need to execute multiple Tasks
(which are awaitable) then Parallel.ForEach
may not be the best choice. It is truly designed for CPU bound processes and does not support async
operations.
You may try to rewrite your code using Task.WhenAll()
:
var tasks = tasklist.Select(RunTask);
// assuming RunTask is declared as `async Task`
await Task.WhenAll(tasks);
This way your are leveraging the use of async
/ await
pattern inside your method call.
If, instead, you realize that your tasks are not properly async
(and are only CPU bound) you may try to execute Parallel.ForEach
inside a simple Task
await Task.Run(() => Parallel.ForEach(tasklist, RunTask);
// assuming RunTask is not `async Task`
First off all you need to distinguish parallel and asynchronous:
When you need to do something with IO asynchronous is usually play.
When you need to do something with computing (like archiving files or image processing) is parallel stuff is usually coming play.
async await pattern its just a shortcut and its not silver bullet.
If You need just to parallel your computation I suggest to use parallel staff from TPL like ParallelForEach, they a playing cool and optimized very good to get maximum performance.
If you are trying to perform some IO operations this can make sense but on more or less huge processing data amount - like server app.
Your processor can't do more then it can
Any parallel staff sill not help you if your task is not parallel. Be aware of any context switch has some cost. TaskSheduler will use queue to decrease threads count but its doing some work again.
Thread new Thread is evil (here at least). Your processor will be switched to one more thread more frequently (more threads - more switches)
Finally: Try not yo use TPL things when you are not aware how does things work. Just use classes you need and dont do optimization that dont really optimize.
PS Use ContinueWith in UI. Anything in TPT will return task that has this method, Updating UI be sure of thread you are currently in.
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.