Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi thread and async at same time

I have the following code:

myObject object1 = null;
Thread obj1Thread = new Thread(() => { object1 = _myService.GetMethod(variable1, variable2); });
obj1Thread.Start();
obj1Thread.Join();


myObject object2 = null;
Thread obj2Thread = new Thread(() => { object2 = _myService.GetMethod2(variable3, variable4); });
obj2Thread.Start();
obj2Thread.Join();

As far as I understand, this code will create 2 new threads, run the specified methods, pause the main thread until both these threads complete, and then continue execution.

Assuming what I say is correct, all fine so far.

Next I want to try this:

myObject object1 = null;
Thread obj1Thread = new Thread(async () => { object1 = await _myService.GetMethod(variable1, variable2); });
obj1Thread.Start();
obj1Thread.Join();


myObject object2 = null;
Thread obj2Thread = new Thread(async () => { object2 = await _myService.GetMethod2(variable3, variable4); });
obj2Thread.Start();
obj2Thread.Join();

Basically adding async and await to each thread.

The compiler accepts this change and it seems to run locally, but is this code ok, and is it likely to cause me any problems further down the line, for example will the threads get confused, fail to wait, mix up results etc.

I have a reasonably good understanding of async and a basic understanding of multi threading, and I cannot think of any reason why this would not work.

The code runs locally, but my worry is that under heavy load on the server issues may appear that were not present in a local version....

like image 409
Alex Avatar asked Mar 12 '26 23:03

Alex


1 Answers

The compiler accepts this change and it seems to run locally, but is this code ok, and is it likely to cause me any problems further down the line, for example will the threads get confused, fail to wait, mix up results etc.

I have a reasonably good understanding of async and a basic understanding of multi threading, and I cannot think of any reason why this would not work.

Yes, this code will cause you problems. The threads are not waiting as you expect. You're passing an async void lambda to the Thread constructor, and that thread will exit as soon as it hits the await in that lambda, before it sets the object1/object2 variable. So it's entirely possible those variables remain null after the Join.

The proper solution, as FCin posted, is to use asynchronous concurrency. (I avoid the term "parallel" here to reduce confusion with the Parallel type and the Task Parallel Library). Asynchronous concurrency uses Task.WhenAll:

// Start both methods concurrently
var task1 = _myService.GetMethod(variable1, variable2);
var task2 = _myService.GetMethod2(variable3, variable4);

// (Asynchronously) wait for them both to complete.
await Task.WhenAll(task1, task2);

// Retrieve results.
myObject object1 = await task1;
myObject object2 = await task2;
like image 73
Stephen Cleary Avatar answered Mar 15 '26 12:03

Stephen Cleary



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!