Threaded ma założyć 4 oddzielnewątki i poczekaj na każdy z nich, aż zakończą. Każdy wątek śpi przez chwilę i kończy się tylko wtedy, gdy udostępniony obiekt Mutex nie jest zajęty przez inny wątek, a następnie sygnalizuje zdarzeniu, że się zakończył (Jest to uproszczona wersja mojego kodu, ale kończy się niepowodzeniem w tym samym miejscu)
Ale dzieje się tak, że przez większość czasu główny wątek będzie czekał wiecznie na jeden z WaitOne () pozornie losowo.
Musiałem też skomentować niektóre części mojego kodu, ponieważ doprowadziło to do jeszcze bardziej nieoczekiwanego zachowania (tj. jakoś po zakończeniu każdego wątku główny wątek wskoczyłby z powrotem do klauzuli for i spowodowałby 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();
}
}
Każda pomoc byłaby świetna
Odpowiedzi:
7 dla odpowiedzi № 1Najprawdopodobniej wszystkie cztery wątki zostaną wykonane:
this.StartIndexCrawling(1, 3, 3 + 1, evs[4]);
Ma to związek z korzystaniem z zamknięć. Wszystkie cztery wątki zostaną powiązane ze zmienną i
i użyj dowolnej wartości, jaką ma po wykonaniu kodu (a nie wartości, gdy Thread
obiekt zostanie utworzony).
Twój kod prawdopodobnie nie zadziała, jeśli wszystkie cztery wątki będą miały tę samą wartość.
0 dla odpowiedzi nr 2
Zobacz odpowiedź Codo.
Oto, co powinieneś zrobić, aby to rozwiązać:
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();