gpt4 book ai didi

c# - WaitOne() 永远等待,即使所有事件都已触发

转载 作者:太空狗 更新时间:2023-10-29 23:00:42 25 4
gpt4 key购买 nike

Threaded 应该创建 4 个独立的线程并等待它们中的每一个直到它们完成。每个线程休眠一段时间,只有当共享互斥对象没有被另一个线程占用时才终止,然后通过一个事件发出它完成的信号(这是我代码的简化版本,但在同一个地方失败)

但是大多数情况下,主线程似乎随机地永远等待 WaitOne() 之一。

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

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

任何帮助都会很棒

最佳答案

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

this.StartIndexCrawling(1, 3, 3 + 1, evs[4]);

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

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

关于c# - WaitOne() 永远等待,即使所有事件都已触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14041951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com