У меня есть следующий шаблон проектирования:
var myObjectWithEvents = new ObjectWithEvents();
using (var mre = new ManualResetEvent(false)) {
var onEvent = new EventHandler<EventArgs>((sender, e) => { mre.Set(); });
try {
myObjectWithEvents.OnEvent += onEvent;
var task = Task.Factory.StartNew(() => {
myObjectWithEvents.DoSomethingThatShouldRaiseAnEvent();
});
var timedOut = !mre.WaitOne(10000);
}
finally {
myObjectWithEvents.OnEvent -= onEvent;
}
}
Моя проблема в том, что if OnEvent
возникает после истечения времени ожидания WaitOne
и выхода выполнения из блока using, локальный обработчик событий onEvent
все равно будет вызываться и пытаться установить ManualResetEvent mre
который уже будет удален, даже если onEvent
должен был быть отменен из OnEvent
.
Простым обходным решением было бы проверить, был ли mre
уже удалено, но, к сожалению, такого поля нет, и я считаю, что перенос mre.Set ()
внутри блока try catch для игнорирования исключения не является чистым, учитывая, что исключение может возникать довольно часто.
Что не могли бы вы предложить как лучший и самый простой способ достижения цели вышеуказанного шаблона кода (т.е. ожидание события, которое будет r aised), не столкнувшись с подобными проблемами?
Edit: Благодаря вашим ответам я создал следующее расширение и заменил mre.Set ()
на mre.TrySet ()
:
public static void TrySet(this ManualResetEvent mre) {
if (!mre.SafeWaitHandle.IsClosed) mre.Set();
}