есть ли гарантия, что метод TrySomething будет ожидать завершения SomeEvent, чтобы был установлен параметр Success, прежде чем его вернуть?
Нет.async void
означает «не уведомлять звонящего, когда я закончу».Таким образом, код, вызывающий ваше событие, не может знать, когда обработчик события завершился, если вы сами не напишите эту дополнительную логику.
И если нет, то как я могу гарантировать, что это происходит?
Ну, это более сложный вопрос.События .NET имеют вид , который я называю «событиями уведомления» - то есть, когда событие запускается, оно уведомляет всех своих слушателей.Нет необходимости «ждать», потому что у слушателя нет возможности отправить отзыв уведомителю.
Ваш код является примером того, что я называю «командным событием» - кодом, которыйevent
, но не соответствует семантике события уведомления.Ваш код требует ответа от обработчика.
Итак, первый вопрос, который вам нужно задать себе: «Действительно ли я хочу, чтобы это было событием?»Один хороший лакмусовый тест для этого: «Могу ли я определить значимую семантику, если есть несколько обработчиков?»
Более конкретно, как должен вести себя ваш код, если несколько обработчиков подключены к событию?Возможно, ответ «это не имеет смысла».Или, возможно, ответ таков: «Я хочу подождать, пока все из них завершатся и будут« успешными », только если все они« успешны »».Или «жди всех и будь« успешным », если любые из них являются« успешными »».Или «дождитесь завершения первого и используйте этот результат».Или «подождите, пока они завершат по одному, останавливаясь на первом успехе».Или «подождите, пока они завершат по одному, останавливаясь на первом сбое».Это тот выбор, который сразу приходит на ум;их может быть больше.
Если ответ «это не произойдет в моем коде» или «более одного обработчика не имеет смысла» или «это слишком сложное решение, чтобы принять его прямо сейчас»тогда соответствующий ответ: удалить event
.Это не событие.Это вызов метода.В терминологии шаблона проектирования events
используются для реализации шаблона наблюдателя , но у вас есть шаблон стратегии , и поэтому event
sплохо подходят.В этом случае вы могли бы использовать ответ Габриэля или что-то подобное, когда вы определяете стратегию с использованием интерфейса, и вместо того, чтобы вызывать событие, вы вызываете метод для этого интерфейса.
Однако,если действительно имеет смысл иметь несколько обработчиков, и - это смысловая семантика, которую вы можете использовать, тогда вам нужно изменить тип EventArgs
, чтобы иметь какое-то "сборщик ответов, а затем попросите ваш код для сбора событий интерпретировать эти ответы.Точный код будет зависеть от необходимой вам семантики.