Thread.join()阻塞主线程直到完成

时间:2019-01-14 12:06:32

标签: c# multithreading

这个问题与我从这个问题中收到的一些评论有关:

Multi thread and async at same time

我有以下代码:

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

我对这段代码的理解如下:

此代码将创建2个新线程,并发运行指定的方法,暂停主线程直到两个线程都完成,然后继续执行。

但是,根据上述问题中的一些评论,obj1Thread.Join();下面的代码要到obj1Thread完成后才能执行。

任何人都可以确认这是否正确吗?

如果是这样,这基本上意味着代码根本不是多线程的,而是按顺序运行的。

另外2个点/问。

-如何使此代码同时运行,而且还要在指定的点上等待所有线程完成,然后再继续主线程

-我运行了10次此方法,并且使用.join()的速度平均快了0.5秒-如果代码基本上按顺序运行,为什么我看到性能提高?

2 个答案:

答案 0 :(得分:1)

您应该为另一个地方的每个线程调用Join()

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

在这种情况下,将启动两个线程,只有这样,您才应该等待它们。

答案 1 :(得分:1)

Join()的调用会阻止当前线程,这意味着在第一次对GetMethod的调用完成之前,不会创建或启动您的第二个线程。

从.NET Framework 4.0开始,建议并行执行两个操作的方法是使用task parallel library (TPL)

您可以使用Parallel.Invoke方法:

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

它采取任意数量的动作并可能并行执行。一旦所有动作完成,该方法就会返回。

如果您要等待并行操作异步完成,则可以启动两个单独的任务,然后使用Task.WhenAll方法等待它们:

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