多线程:WaitAll不会按预期等待

时间:2011-02-19 10:33:34

标签: c# multithreading waithandle

我有一个线程正在调用两个单独的线程来做一些工作。每当任何一个作业完成一个Waithandle.Set(调用0并且在父工作线程结束时,我想等待两者完成,然后继续。但是priceA()仍然是先出现然后PriceB ()。

new Thread(() =>
                           {
                               new Thread(() =>
                               {
                                   PriceA = _service.GetPriceA();
                                   _waithandle[0].Set();
                               }).Start();

                               new Thread(() =>
                               {
                                   PriceB = _service.GetPriceB();
                                   _waithandle[1].Set();
                               }).Start();

                               WaitHandle.WaitAll(_waithandle);
                           }).Start();
Console.WriteLine("Hello");

我错过了什么?

更新

private EventWaitHandle[] _waithandle;

CTOR:

 _waithandle[0] = new ManualResetEvent(false);
 _waithandle[1] = new ManualResetEvent(false);

3 个答案:

答案 0 :(得分:4)

你正在创建一个单独的线程等待......但是你给出的语句之后的代码将继续,因为你没有在那个线程中等待。换句话说,您正在创建三个线程:

  • 线程X:创建线程A和B,然后等待它们完成
  • 线程A:获取PriceA然后设置waitHandle [0]
  • 线程B:获取PriceB然后设置waitHandle [1]

但是在等待之后,线程X没有做任何事情,那么等待它的重点是什么?

此外,在您创建的额外线程上调用Join会更简单。事实上,如果您只需要在“当前”线程中等待,那么首先只需要一个额外线程:

Thread t = new Thread(() => { PriceA = _service.GetPriceA(); });
t.Start();
PriceB = _service.GetPriceB();
t.Join();
// Other code

当您到达“其他代码”时,PriceA和PriceB都将被设置。当然,这缺少相当多的错误处理......但是当你有一个比当前过于复杂的代码更简单的起点时,这更容易添加。

答案 1 :(得分:0)

您是否正确重置了_waithandle[0][1]?例如:

_waithandle[0] = new ManualResetEvent(false);
_waithandle[1] = new ManualResetEvent(false);

答案 2 :(得分:0)

new Thread(() =>
                           {
                               new Thread(() =>
                               {
                                   _priceA = _service.GetPriceA();
                                   _waithandle[0].Set();
                               }).Start();

                               new Thread(() =>
                               {
                                   _priceB = _service.GetPriceB();
                                   _waithandle[1].Set();
                               }).Start();

                               WaitHandle.WaitAll(_waithandle);
                               PriceA = _priceA;
                               PriceB = _priceB;
                           }).Start();

这对我有用。 Culprit是PriceA和PriceB的INotifyChangedProperty(),它过早地更新了UI,使我的waitall多余。如果其他人有类似的问题......