Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nicer pattern for starting tasks and getting their return values

I'm implementing some asynchronous work and cant help but feel I'm ending up with a really ugly construction and I'm wondering if and how this could be rewritten to something that 'feels better'.

 var tasks = new List<Task>();

 var t1 = new Task<Guid>(() => DoSomeStuff<Xyz>(dtx, e1, M1));
 var t2 = new Task<Guid>(() => DoSomeStuff<Qrs>(dtx, e2, M2));
 var t3 = new Task<Guid>(() => DoSomeStuff<Abc>(dtx, e3, M3));

 tasks.Add(t1);
 tasks.Add(t2);
 tasks.Add(t3);

 tasks.ForEach(x => x.Start());

 Task.WaitAll(tasks.ToArray<Task>());

 returnDto.t1value = t1.Result;
 returnDto.t2value = t2.Result;
 returnDto.t3value = t3.Result;

Variable names have been changed for brevity, there are actually a lot more tasks. Tasks can all run independently, but all have to be completed before we can continue.

DoSomeStuff looks like this:

private Guid DoSomeStuff<T>(DependentTransaction dtx, T thing, Func<T, Guid> method)
like image 391
Apeiron Avatar asked Dec 03 '25 17:12

Apeiron


1 Answers

It would be much easier to use async-await to wait asynchronously, Task.WhenAll to wait for multiple tasks and get their results and Task.Run to run DoSomeStuff in parallel:

Guid[] results = await Task.WhenAll(
    Task.Run(() => DoSomeStuff<Xyz>(dtx, e1, M1)),
    Task.Run(() => DoSomeStuff<Qrs>(dtx, e2, M2)), 
    Task.Run(() => DoSomeStuff<Abc>(dtx, e3, M3)));
like image 190
i3arnon Avatar answered Dec 06 '25 07:12

i3arnon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!