Używam aplikacji, która synchronizuje wątki za pomocą ManualResetEvent. FxCop kazał mi wyrzucić te przedmioty. Znalazłem następującą dyskusję, która powiedziała mi to samo:Kiedy należy zdemontować ManualResetEvent?
Do I need to Dispose() or Close() an EventWaitHandle?
Ale nie wiem kiedy do dysponowania instancję ManualResetEvent.
Następujący kod uproszczony pokazuje problem:
private void btn_Click(object sender, EventArgs e)
{
var mre = new ManualResetEvent(false);
new Thread(() => this.SetEvent(mre)).Start();
for (int i = 0; i < 10; ++i)
{
new Thread(() => this.WaitFor(mre)).Start();
}
}
private void SetEvent(ManualResetEvent manualResetEvent)
{
Thread.Sleep(10000);
manualResetEvent.Set();
}
private void WaitFor(ManualResetEvent manualResetEvent)
{
manualResetEvent.WaitOne();
}
Problemem jest to, że wiele instancji ManualResetEvent istnieć i wielu wątków czeka na każdym przypadku.
Jeśli zapamiętuję instancje na liście, nie wiem, kiedy je zutylizować. Pozbycie się go po wywołaniu WaitOne() wywoła je kilka razy i być może zostanie usunięte, podczas gdy inne wątki wciąż czekają.
Wątek, który utworzył wydarzenie, nie ma żadnego odniesienia do niego. Wątek setera nie powinien go usuwać, ponieważ na MRE czekają inne wątki. Każdy wątek oczekujący nie jest w stanie go usunąć, jak wspomniano wcześniej.
Pytanie brzmi: Kiedy należy usunąć ten podręcznik ManualResetEvent?
Kod jest bezsensowny i jest tylko * jeden * wystąpienie MRE. Pozbycie go na końcu metody jest w porządku. –
Nie, nie sądzę.Kod tworzący MRE to obsługa zdarzeń click button. Możesz go wielokrotnie kliknąć, tworząc wiele MRE. Powyższy kod jest uproszczony. Usunięcie MRE na końcu tej metody nie będzie działać, ponieważ istnieje 11 wątków, które używają tego MRE po zakończeniu metody. Wątek ustawiający czeka 10 sekund, a 10 innych wątków czeka na to MRE. –