В C # при переопределении метода разрешается делать асинхронное переопределение, когда исходный метод не был. Это похоже на плохую форму.
Пример, который привел меня к этому, был следующим - меня привели, чтобы помочь с проблемой нагрузочного теста. Около 500 одновременно работающих пользователей процесс входа в систему будет нарушен в цикле перенаправления. IIS регистрировал исключения с сообщением «Асинхронный модуль или обработчик завершены, пока асинхронная операция еще не завершена». Некоторые поиски привели меня к мысли, что кто-то злоупотребляет async void
, но мои быстрые поиски по источнику ничего не смогли найти.
К сожалению, я искал 'async \ svoid' (поиск по регулярному выражению), когда мне следовало искать что-то более похожее на 'async \ s [^ T]' (предполагая, что Задача не была полностью квалифицирована ... Вы понимаете, в чем дело).
То, что я позже нашел, было async override void onActionExecuting(...
в базовом контроллере. Очевидно, что это должно быть проблемой, и это было. Исправление этого (сделав его синхронным на данный момент) решило проблему.
Вернемся к вопросу: почему вы можете пометить переопределение как асинхронное, когда вызывающий код не может его ожидать?
Task
.Ответы:
Асинхронное ключевое слово позволяет метод использовать
await
синтаксис в его определении. Я могу использоватьawait
любой метод, который возвращаетTask
тип независимо от того, является ли он асинхронным методом.void
является допустимым (хотя и не поощряемым ) типом возврата для асинхронного метода, так почему бы его не разрешить? Со стороныasync
не позволяет ничего, что вы не могли бы сделать без него. Метод, с которым у вас возникли проблемы, мог бы быть написан так, чтобы он вел себя точно так же, не будучи асинхронным. Его определение было бы более многословным.Для абонентов,
async T
метод является нормальным методом , который возвращаетT
(который ограниченvoid
,Task
илиTask<A>
). То, что это асинхронный метод, не является частью интерфейса. Обратите внимание, что следующий код недопустим:Он (или аналогичный код в абстрактном классе) выдает следующее сообщение об ошибке в VS2012:
Если я действительно хотел , чтобы метод в интерфейсе или родительском классе был типично асинхронным, я не могу использовать это
async
для передачи информации. Если бы я хотел реализовать его с помощьюawait
синтаксиса, мне нужно было бы иметь возможность асинхронного переопределения (в случае родительского класса).источник
override
, но вот о чем вопрос.async
, что интерфейс метода не меняется, только то, что синтаксически разрешено в его определении, поэтому не имеет значения, является ли это переопределением или нет.async
модификатор можно применять только к реализациям. Вы не можете объявить метод асинхронным в интерфейсе, например, подчеркнув, что метод является асинхронным или нет, не является частью интерфейса.Единственная цель ключевого слова async - сделать ожидание в теле этой функции ключевым словом. Это необходимо для того, чтобы добавление функции await не нарушало существующий код. Microsoft решила использовать опцию «ждать». Для функции, которая не помечена как асинхронная, вы можете определить переменную с именем await без проблем.
Следовательно, async не является частью сигнатуры функции и не имеет семантического значения в сгенерированном коде IL. Компилятор должен знать, как правильно скомпилировать функцию. Он также дает указание компилятору гарантировать, что возвращаются только Task, Task <T> или void.
источник