首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >即使触发了所有事件,WaitOne()也会永远等待

即使触发了所有事件,WaitOne()也会永远等待
EN

Stack Overflow用户
提问于 2012-12-26 22:26:51
回答 2查看 1.4K关注 0票数 5

Threaded假设创建4个独立的线程,并等待每个线程,直到它们完成。每个线程都会休眠一段时间,只有当共享的Mutex对象没有被另一个线程占用时才会终止,然后通过事件通知它已经结束(这是我的代码的简化版本,但在同一位置失败)

但是,大多数情况下,主线程似乎是随机地在其中一个WaitOne()函数上永远等待。

此外,我不得不注释掉代码的某些部分,因为它导致了更多的意外行为(即,在每个线程完成后,主线程会以某种方式跳回for子句并导致IndexOutOfBounds)。

代码语言:javascript
复制
class Threading
{
    static Mutex CM;
    static List<Manga> SharedList;
    static ManualResetEvent CEvent = new ManualResetEvent(false);
    static ManualResetEvent Event1 = new ManualResetEvent(false);
    static ManualResetEvent Event2 = new ManualResetEvent(false);
    static ManualResetEvent Event3 = new ManualResetEvent(false);
    static ManualResetEvent Event4 = new ManualResetEvent(false);

   public List<Manga> ThreadedMangaIndexCrawl(int MaxThreads)
   {
       CM = new Mutex(false);
       SharedList = new List<Manga>();

       ManualResetEvent[] evs = new ManualResetEvent[4];
       evs[0] = Event1;    // Event for t1
       evs[1] = Event2;    // Event for t2
       evs[2] = Event3;    // Event for t3
       evs[3] = Event4;    // Event for t4

       /*for (int i = 0; i < MaxThreads + 1; i++)
       {
           if (i > MaxThreads)
           { break; }
           Thread t = new Thread(() => this.StartIndexCrawling(1,i,i+1,evs[i]));
           t.Start();
       }*/
       int i = 0;
       Thread t1 = new Thread(() => this.StartIndexCrawling(1, i, i + 1, evs[i]));
       t1.Name = "Thread" + i;
       t1.Start();
       i++;
       Thread t2 = new Thread(() => this.StartIndexCrawling(1, i, i + 1, evs[i]));
       t2.Name = "Thread" + i;
       t2.Start();
       i++;
       Thread t3 = new Thread(() => this.StartIndexCrawling(1, i, i + 1, evs[i]));
       t3.Name = "Thread" + i;
       t3.Start();
       i++;
       Thread t4 = new Thread(() => this.StartIndexCrawling(1, i, i + 1, evs[i]));
       t4.Name = "Thread" + i;
       t4.Start();


      /* foreach (var e in evs)
       { 
           e.WaitOne(); 

       }*/

       evs[0].WaitOne();
       evs[1].WaitOne();
       evs[2].WaitOne();
       evs[3].WaitOne(); 

       return SharedList;
   }

   void StartIndexCrawling(int Target, int Start, int End, ManualResetEvent E)
   {
       Thread.Sleep(1000);
       CM.WaitOne();
       CM.ReleaseMutex();
       E.Set();
   }
}

任何帮助都是最好的

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-26 22:41:54

最有可能的是,所有四个线程都将执行:

代码语言:javascript
复制
this.StartIndexCrawling(1, 3, 3 + 1, evs[4]);

这与您使用闭包有关。所有四个线程都将绑定到变量i,并在代码执行后使用它所具有的任何值(而不是创建Thread对象时的值)。

如果所有四个线程都使用相同的值,则您的代码不太可能工作。

票数 7
EN

Stack Overflow用户

发布于 2012-12-26 22:46:15

请参阅Codo的答案。

下面是你应该做的来解决这个问题:

代码语言:javascript
复制
   int i = 0;
   Thread t1 = new Thread(() => this.StartIndexCrawling(1, 0, 1, Event1));
   t1.Name = "Thread" + i;
   t1.Start();
   i++;
   Thread t2 = new Thread(() => this.StartIndexCrawling(1, 1, 2, Event2));
   t2.Name = "Thread" + i;
   t2.Start();
   i++;
   Thread t3 = new Thread(() => this.StartIndexCrawling(1, 2, 3, Event3));
   t3.Name = "Thread" + i;
   t3.Start();
   i++;
   Thread t4 = new Thread(() => this.StartIndexCrawling(1, 3, 4, Event4));
   t4.Name = "Thread" + i;
   t4.Start();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14041951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档