У меня есть следующий шаблон проектирования:
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;
}
}
Моя проблема в том, что если OnEvent
возникает после истечения времени WaitOne
, а выполнение выполняется из блока использования, локальный обработчик событий OnEvent
все равно будет вызываться и попытаться установить ManualResetEvent mre
, который будет уже были удалены, хотя OnEvent
должен был быть незарегистрирован из OnEvent
.
Простым обходным решением было бы проверить, был ли уже установлен mre
, но, к сожалению, такого поля нет, и я считаю, что обертка mre.Set()
внутри блока catch try для игнорирования исключения не является чистой, учитывая, что исключение может происходить довольно часто.
Что вы предложите как лучший и самый простой способ достичь цели вышеуказанного шаблона кода (т.е. ожидание создания события), не сталкиваясь с такой проблемой?
Изменить:. Благодаря вашим ответам я создал следующее расширение и заменил mre.Set()
на mre.TrySet()
:
public static void TrySet(this ManualResetEvent mre) {
if (!mre.SafeWaitHandle.IsClosed) mre.Set();
}