多线程:WaitAll 未按预期等待

发布于 2024-10-17 22:32:33 字数 1083 浏览 2 评论 0原文

我有一个线程正在调用两个单独的线程来做一些工作。每当任何作业完成时,都会调用 Waithandle.Set(0 ,并且在父工作线程结束时,我想在继续之前等待所有作业都完成。但价格A()仍然先出现,然后是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);

I have a thread that is calling two separate threads to do somework. Whenever any of the jobs is finished a Waithandle.Set(0 is called and at the end of the parent worker thread I wanted to WaitAll for both to be finished, before i continue. But priceA() is still coming up first and then 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");

What am I missing?

Update:

private EventWaitHandle[] _waithandle;

Ctor:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烙印 2024-10-24 22:32:33

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

  • 线程 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 都会有已设置。当然,这缺少大量的错误处理......但是当您有一个比当前过于复杂的代码更简单的起点时,添加起来会更容易。

You're creating a separate thread to wait... but the code after the statement you've given will continue because you're not waiting in that thread. In other words, you're creating three threads:

  • Thread X: Creates threads A and B, then waits for them to finish
  • Thread A: Gets PriceA and then sets waitHandle[0]
  • Thread B: Gets PriceB and then sets waitHandle[1]

But thread X is doing nothing after it's waited, so what's the point of waiting within it?

Additionally, it would be a lot simpler to just call Join on the extra threads that you've created. In fact, if you only need to wait in the "current" thread, you only need one extra thread in the first place:

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

By the time you reach "other code", both PriceA and PriceB will have been set. Of course, this is missing a considerable amount of error handling... but that's easier to add when you've got a simpler starting point than your currently over-complicated code.

独孤求败 2024-10-24 22:32:33
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();

这为我完成了工作。罪魁祸首是 PriceA 和 PriceB 的 INotifyChangedProperty(),它过早更新了 UI,使我的等待变得多余。万一其他人也有类似的问题...

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

This did the job for me. Culprit was the INotifyChangedProperty() of the PriceA and PriceB which updated the UI too early making my waitall redundant. In case someone else has a similar issue...

风尘浪孓 2024-10-24 22:32:33

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

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

Are you resetting correctly the _waithandle[0] and [1]? For example:

_waithandle[0] = new ManualResetEvent(false);
_waithandle[1] = new ManualResetEvent(false);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文