Alex
Alex

Reputation: 3968

Thread.join() blocking main thread until complete

This question relates to some comments I received from this question:

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

My understanding of this code was as follows:

This code will create 2 new threads, run the specified methods concurrently, pausing the main thread until both these threads complete, and then continue execution.

However, according to some of the comments in the above question, the code below obj1Thread.Join(); will not execute until obj1Thread has completed.

Can anyone confirm if this is correct?

If so, this basically means the code is not multithreaded at all, but runs sequentially.

2 further points/quesitons.

-How can I make this code run concurrently, but also wait at a specified point for all threads to complete before the main thread continues

-I ran this method 10 times, and with .join() it was .5 seconds faster on average - why am I seeing a performance improvement if the code is basically running sequentially?

Upvotes: 0

Views: 533

Answers (2)

mm8
mm8

Reputation: 169340

A call to Join() blocks the current thread which means that your second thread isn't created nor started before the first call to GetMethod has completed.

Starting with .NET Framework 4.0, the recommended way to execute two operations in parallel is to use the task parallel library (TPL).

You could use the Parallel.Invoke method:

myObject object1 = null;
myObject object2 = null;
Parallel.Invoke(
    () => object1 = _myService.GetMethod(variable1, variable2),
    () => object2 = _myService.GetMethod2(variable3, variable4)
);

It takes an arbitrary number of actions and executes them, possibly in parallel. The method returns once all actions have completed.

If you want to wait for the parallel operations to complete asynchronously, you could start two individual tasks and await them using the Task.WhenAll method:

myObject object1 = null;
myObject object2 = null;
Task t1 = Task.Run(() => object1 = _myService.GetMethod(variable1, variable2));
Task t2 = Task.Run(() => object2 = _myService.GetMethod(variable3, variable4));
await Task.WhenAll(t1, t2);

Upvotes: 1

Roman
Roman

Reputation: 12201

You should call Join() for each thread in another place:

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

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

obj1Thread.Join();
obj2Thread.Join();

In this case two threads will be started and only then you should wait for them.

Upvotes: 1

Related Questions