Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
В этой статье рассматриваются следующие ошибки компилятора:
-
CS1983: так как это асинхронный метод, возвращаемое выражение должно иметь тип "
T" вместо "Task<T>". - CS1985: нельзя использовать await в блоке catch.
-
CS1986: "
await" требует, чтобы тип имел подходящий метод 'GetAwaiter'. - CS1989: асинхронные лямбда-выражения нельзя преобразовать в деревья выражений.
- CS1991: "Тип" не может реализовать "событие", так как это событие среды выполнения Windows, и "событие" является обычным событием .NET.
-
CS1992: оператор '
await' может использоваться только в том случае, если он содержится в методе или лямбда-выражении, помеченном модификатором async. -
CS1994: Модификатор '
async' можно использовать только в методах, имеющих тело. -
CS1995: оператор '
await' может использоваться только в выражении запроса в первом выражении коллекции начального предложения 'from' или в выражении коллекции предложения 'join'. - CS1996: не удается ожидать в тексте инструкции блокировки.
- CS1997: так как функция является асинхронным методом, возвращающим значение, ключевое слово возвращаемого значения не должно следовать выражению объекта.
-
CS1998: этот асинхронный метод не имеет операторов "
await" и будет выполняться синхронно. Рассмотрите возможность использования оператора "await" для ожидания неблокирующих вызовов API илиawait Task.Run(...)"" для выполнения работы с ЦП на фоновом потоке. - CS4001: Не удается дождаться выражения.
-
CS4003: '
await' нельзя использовать в качестве идентификатора в асинхронном методе или лямбда-выражении. - CS4005: асинхронные методы не могут иметь параметры типа указателя.
- CS4006: __arglist запрещено в списке параметров асинхронных методов.
-
CS4007: Экземпляр типа не может быть сохранен через границу «
await» или «yield». -
CS4008: не удается ожидать "
void". - CS4009: Точка входа, возвращающая void или int, не может быть асинхронной.
- CS4010: не удается преобразовать асинхронное выражение в тип делегата. Асинхронное выражение может возвращать void, Task или Task<T>, ни одно из которых не преобразуется в тип.
-
CS4011: "
await" требует, чтобы возвращаемый тип '{1}.GetAwaiter()' имел подходящие члены IsCompleted, OnCompleted и GetResult, а также реализовывал INotifyCompletion или ICriticalNotifyCompletion. - CS4012: параметры типа нельзя объявлять в асинхронных методах или асинхронных лямбда-выражениях.
-
CS4014: так как этот вызов не ожидается, выполнение текущего метода продолжается до завершения вызова. Рассмотрите возможность применения
awaitоператора к результату вызова. - CS4015: 'MethodImplOptions.Synchronized' нельзя применить к асинхронному методу.
- CS4016: Поскольку это асинхронный метод, возвращаемое выражение должно быть типа, подобного типу Task, а не объявленного типа.
- CS4027: тип выражения не реализует обязательный элемент.
-
CS4028: "
await" требует, чтобы тип содержал соответствующий метод 'GetAwaiter'. Возможно, отсутствует директива using для 'System'? - CS4029: не удается вернуть выражение типа void.
- CS4030: атрибут безопасности нельзя применить к методу Async.
- CS4031: асинхронные методы не допускаются в интерфейсе, классе или структуре с атрибутом SecurityCritical или SecuritySafeCritical.
-
CS4032: оператор '
await' может использоваться только в асинхронном методе. Рекомендуется пометить этот метод модификатором async и изменить тип возвращаемого значения на "Task<T>". -
CS4033: оператор '
await' можно использовать только в асинхронном методе. Рекомендуется пометить этот метод модификатором "async" и изменить тип возвращаемого значения на "Task". -
CS4034: оператор '
await' может использоваться только в асинхронном методе. Рекомендуется пометить этот метод модификатором async. - CS8031: Асинхронное лямбда-выражение, преобразованное в делегат, возвращающий задачу, не может возвращать значение.
-
CS8100: оператор '
await' нельзя использовать в инициализаторе статических переменных скриптов. - CS8177: Асинхронные методы не могут иметь локальные переменные по ссылке.
-
CS8178: ссылка, возвращаемая вызовом метода, не может быть сохранена через границу "
await" или "yield". - CS8204: для типа, используемого в качестве AsyncMethodBuilder для целевого типа, его свойство Task должно возвращать целевой тип, а не объявленный тип.
-
CS8403: Метод с итераторным блоком должен быть '
async' для возврата IAsyncEnumerable<T>. - CS8411: асинхронная инструкция foreach не может работать с переменными типа, так как тип не содержит подходящего общедоступного экземпляра или определения расширения для обязательного элемента.
- CS8892: метод не будет использоваться в качестве точки входа, так как обнаружена синхронная точка входа.
- CS8935: атрибут AsyncMethodBuilder запрещен для анонимных методов без явного типа возвращаемого значения.
- CS8940: ожидался универсальный тип возвращаемой задачи, но тип, найденный в атрибуте AsyncMethodBuilder, не подходит. Он должен быть несвязанным универсальным типом arity one, а его содержащий тип (если таковой) должен быть не универсальным.
-
CS9123: оператор '
&' не должен использоваться для параметров или локальных переменных в асинхронных методах. -
CS9330: '
MethodImplAttribute.Async' нельзя применять вручную к методам. Пометьте метод async.
Требования к выражению Await
- CS1985: нельзя использовать await в блоке catch.
-
CS1986: "
await" требует, чтобы тип имел подходящий метод 'GetAwaiter'. -
CS1992: оператор '
await' может использоваться только в том случае, если он содержится в методе или лямбда-выражении, помеченном модификатором 'async' . -
CS1995: оператор '
await' может использоваться только в выражении запроса в первом выражении коллекции исходного предложения 'from' или в выражении коллекции предложения 'join'. - CS1996: Недопустимо использование await в теле инструкции блокировки.
-
CS4008: не удается ожидать "
void". -
CS4032: оператор '
await' может использоваться только в асинхронном методе. Рекомендуется пометить этот метод модификатором "async" и изменить тип возвращаемого значения на "Task<T>". -
CS4033: оператор '
await' можно использовать только в асинхронном методе. Рекомендуется пометить этот метод модификатором "async" и изменить тип возвращаемого значения на "Task". -
CS4034: оператор '
await' может использоваться только в асинхронном методе. Рекомендуется пометить этот метод модификатором async. -
CS8178: ссылка, возвращаемая этим вызовом, не может быть сохранена через границу "
await" или "yield". - CS8411: асинхронная инструкция foreach не может работать с переменными типа, так как тип не содержит подходящего общедоступного экземпляра или определения расширения для обязательного элемента.
- CS4001: нельзя ожидать выражения.
-
CS4003: '
await' нельзя использовать в качестве идентификатора в асинхронном методе или лямбда-выражении. -
CS4007: экземпляр типа нельзя сохранить через границу "
await" или "yield". -
CS4011: "
await" требует, чтобы тип возвращаемого значения "GetAwaiter()" имел подходящие члены IsCompleted, OnCompleted и GetResult, а также реализует "INotifyCompletion" или "ICriticalNotifyCompletion". - CS4027: тип не реализует обязательный элемент.
-
CS4028: "
await" требует, чтобы тип имел подходящий метод 'GetAwaiter'. Возможно, пропущена директива using для 'System'? -
CS8100: оператор '
await' нельзя использовать в инициализаторе статических переменных скриптов.
В следующих элементах объясняется, как исправить каждую ошибку. Дополнительные сведения об оператореawait и паттерне ожидания см. в статье Асинхронное программирование с использованием async и await.
- Добавьте модификатор
asyncк методу или лямбда-выражению, содержащему выражениеawait(CS1992, CS4032, CS4033, CS4034). Компилятору требуетсяasyncмодификатор, чтобы он смог создать компьютер состояния, который обрабатывает асинхронную приостановку и возобновление. Три вариации этой ошибки предоставляют контекстно-зависимые рекомендации по правильному возвращаемому типу. - Переместите
awaitвыражения изcatchблоков, когда вы нацеливаетесь на C# 5 или более раннюю версию (CS1985). Начиная с C# 6, компилятор поддерживаетawaitв обоихcatchиfinallyблоках. Эта ошибка больше не создается в C# 6 и более поздних версиях. - Перемещение
awaitвыражений из блоков инструкцийlock(CS1996). Асинхронная приостановка при удержании блокировки рискует взаимоблокировкой. Блокировка удерживается при переключениях потоков, где другой код может ожидать этой же блокировки. - Реструктурировать выражения запросов так, чтобы
awaitотображалось только в первом выражении коллекции начального предложенияfromили в выражении коллекции предложенияjoin(CS1995). Другие предложения запросов преобразуются в лямбда-выражения, которые не поддерживают асинхронную приостановку. - Измените тип ожидаемого выражения так, чтобы он разрешал доступ к методу
, который следует паттерну ожидателя ( CS1986 ,CS4028 ). Тип может реализовать шаблон напрямую или через метод расширения.GetAwaiterЕсли метод существует, но отсутствует директиваusingдляSystem, компилятор выдает более специфическое сообщение CS4028 вместо CS1986. - Убедитесь, что тип awaiter, возвращаемый
GetAwaiter(), имеетIsCompleted,OnCompleted, и членыGetResult, и реализует INotifyCompletion или ICriticalNotifyCompletion (CS4011, CS4027).awaitВыражение зависит от этих участников, чтобы проверить статус завершения, зарегистрировать продолжения и получить результаты. - Измените возвращаемый тип вызываемого метода на
void, Task или Task<TResult>, чтобы результат можно было ожидать (CS4008). Нельзя ожидатьvoid-возвращающего метода, так как нет объекта задачи для отслеживания завершения или распространения исключений. - Измените ожидаемое выражение на тип, поддерживающий шаблон ожидания (CS4001). Такие типы, как
intиstringдругие встроенные типы, не имеютGetAwaiterметода и не могут быть ожидаться напрямую. - Сохраните результат вызова метода ref-returning в локальной переменной перед использованием
await(CS8178). Ссылка, возвращаемая методом, не может быть сохранена через границуawait, так как асинхронная машина состояний может приостановить и возобновить работу в другом потоке или контексте, делая ссылку недействительной. - Реализуйте IAsyncEnumerable<T> для типа коллекции или добавьте доступный метод
GetAsyncEnumerator, который возвращает тип с элементамиCurrentиMoveNextAsync(CS8411). Операторawait foreachтребует , чтобы тип коллекции соблюдал асинхронную схему перечисления. - Переименуйте любую локальную переменную или параметр, именуемую
awaitasyncвнутри метода или лямбда-выражения (CS4003). Внутри асинхронных контекстовawaitявляется контекстным ключевым словом и не может использоваться в качестве идентификатора. -
awaitПереместите выражение из инициализатора статических переменных скриптов и в текст метода (CS8100). Статические инициализаторы выполняются вне асинхронного контекста, поэтомуawaitв этом расположении недоступны. - Реструктурировать код таким образом, чтобы экземпляры
ref structне требовалось сохранять на границеawaitилиyield(CS4007). Асинхронная машина состояний хранит локальные переменные в куче, аref structтипы по конструкции привязаны к стеку. Они не могут быть безопасно перемещены в кучу в точках приостановки.
Требования к подписи асинхронного метода
-
CS1983: так как это асинхронный метод, возвращаемое выражение должно иметь тип T, а не "
Task<T>". -
CS1994: Модификатор '
async' можно использовать только в методах, имеющих тело. - CS4009: Точка входа, возвращающая void или int, не может быть асинхронной.
- CS8892: метод не будет использоваться в качестве точки входа, так как обнаружена синхронная точка входа.
- CS8935: атрибут AsyncMethodBuilder запрещен для анонимных методов без явного типа возвращаемого значения.
- CS8940: ожидался универсальный тип возвращаемой задачи, но тип, найденный в атрибуте AsyncMethodBuilder, не подходит. Он должен быть несвязанным универсальным типом arity one, а его содержащий тип (если таковой) должен быть не универсальным.
-
CS8403: метод с блоком итератора должен иметь значение "
async" для возврата "{1}". -
CS9330: '
MethodImplAttribute.Async' нельзя применять вручную к методам. Пометьте метод 'async'. - CS4005: асинхронные методы не могут иметь параметры типа указателя.
- CS4006: __arglist запрещено в списке параметров асинхронных методов.
- CS4010: Невозможно преобразовать асинхронное лямбда-выражение в тип делегата. Асинхронное лямбда-выражение может возвращать void, Task или Task<T>, ни один из которых не преобразуется в данный возвращаемый тип.
- CS4012: параметры типа нельзя объявлять в асинхронных методах или асинхронных лямбда-выражениях.
- CS4015: MethodImplOptions.Synchronized нельзя применить к асинхронному методу.
- CS4016: так как это асинхронный метод, возвращаемое выражение должно быть типом задачи, а не типом.
- CS8031: Асинхронное лямбда-выражение, преобразованное в делегат, возвращающий задачу, не может возвращать значение.
- CS8204: Чтобы тип можно было использовать в качестве AsyncMethodBuilder, его свойство Task должно возвращать необходимый тип вместо объявленного типа.
В следующих элементах объясняется, как исправить каждую ошибку. Дополнительные сведения о объявлениях асинхронных методов см. модификатор async и асинхронные возвращаемые типы.
- Измените выражение возврата, чтобы соответствовать базовому типу результата метода асинхронного метода (CS1983, CS4016). При возврате
Task<T>асинхронного метода операторreturnдолжен указать значение типаT, а неTask<T>, потому что созданная компилятором машина состояний автоматически упаковывает значение в задачу. CS1983 появляется, когда метод возвращаетсяTask<T>, а выражение —T; CS4016 охватывает общий случай, когда тип возвращаемого выражения не соответствует. -
asyncУдалите модификатор из методов, которые не имеют текста, например абстрактных методов или объявлений методов интерфейса (CS1994). Дляasyncмодификатора требуется тело метода, чтобы компилятор смог создать реализацию автомата состояний. - Измените тип возврата асинхронной точки входа на Task или Task<TResult> (CS4009). Начиная с C# 7.1, определенный метод может быть
Main, но он должен возвращать илиasyncTaskTask<int>, и - не являются допустимыми сигнатурами точки входа. - Удалите или переименуйте одну точку входа, если проект содержит синхронный и асинхронный
Mainметод (CS8892). Компилятор выбирает синхронную точку входа и выдает это предупреждение для асинхронного кандидата, который он игнорирует. - Добавьте явный тип возвращаемого значения в лямбда-выражение перед применением атрибута
[AsyncMethodBuilder](CS8935). Компилятор не может разрешить тип построителя для анонимного метода, тип возвращаемого значения которого выводится, так как атрибут должен соответствовать определенному типу возвращаемого значения во время компиляции. - Измените тип, указанный в
[AsyncMethodBuilder]атрибуте, на несвязанный универсальный тип arity one, напримерMyTaskMethodBuilder<>вместоMyTaskMethodBuilder<T>не универсального типа (CS8940). Содержащий тип построителя, если таковой имеется, также должен быть не универсальным. Компилятору требуется эта структура, чтобы он мог построить конструктор для любого конкретного типа, подобного задаче, как возвращаемого типа. - Замените вручную атрибут
[MethodImpl(MethodImplOptions.Async)]наasyncв объявлении метода (CS9330). ФлагMethodImplOptions.Asyncзарезервирован для внутреннего использования среды выполнения и не может применяться непосредственно в пользовательском коде. -
asyncДобавьте модификатор в методы, содержащие блоки итератора и возвращаемые IAsyncEnumerable<T> или IAsyncEnumerator<T> (CS8403). Без модификатораasyncкомпилятор обрабатывает метод как синхронный итератор и не может создать машину состояний для асинхронного потока. - Удалите параметры типа указателя из асинхронных методов (CS4005). Указатели ссылаются на фиксированные расположения памяти, которые нельзя безопасно сохранить в асинхронных точках приостановки, где выполнение может возобновиться в другом потоке.
- Удалите
__arglistиз списков параметров асинхронного метода (CS4006). Списки аргументов переменной длины зависят от соглашений о вызовах на основе стека, несовместимых с асинхронной машиной состояний, расположенной в куче. - Удалите параметры
ref,inили такие параметры типаout, какref structили Span<T>, из асинхронных методов или асинхронных лямбда-выражений (ReadOnlySpan<T>). Эти типы параметров привязаны к стеку и не могут быть безопасно захвачены в замыкании асинхронной машины состояний, выделенном в куче. - Измените тип целевого делегата так, чтобы он соответствовал типу возврата асинхронной лямбда-выражения (CS4010). Асинхронная лямбда может возвращать
void, Task или Task<TResult>, и компилятор не может преобразовать их в произвольные типы делегатов, ожидающих различные типы возвращаемых значений. -
returnУдалите выражение из асинхронной лямбды, назначенной не универсальному делегатуTask, или измените тип делегата наFunc<Task<T>>, чтобы лямбда могла возвращать значение (CS8031). Делегат без универсальногоTaskвозврата представляет асинхронную операцию без результата, поэтому возврат значения является несоответствием типа. -
[MethodImpl(MethodImplOptions.Synchronized)]Удалите атрибут из асинхронных методов (CS4015). ОпцияSynchronizedполучает блокировку для выполнения всего метода, но асинхронный метод может приостанавливаться и возобновляться на разных потоках, что делает семантику блокировки неопределенной. - Исправьте настраиваемый
AsyncMethodBuilderтип, чтобы егоTaskсвойство было того же типа, что и объявленный возвращаемый тип асинхронного метода (CS8204). Компилятор использует свойство построителяTaskдля получения конечного объекта задачи, поэтому несоответствие типов препятствует правильной работе машины состояний.
Асинхронные методики
- CS1989: асинхронные лямбда-выражения нельзя преобразовать в деревья выражений.
- CS1991: "Тип" не может реализовать "событие", так как это событие среды выполнения Windows, и "событие" является обычным событием .NET.
- CS1997: так как функция является асинхронным методом, возвращающим значение, ключевое слово возвращаемого значения не должно следовать выражению объекта.
-
CS1998: этот асинхронный метод не имеет операторов "
await" и будет выполняться синхронно. Рассмотрите возможность использования оператора "await" для ожидания неблокирующих вызовов API илиawait Task.Run(...)"" для выполнения работы с ЦП на фоновом потоке. -
CS4014: так как этот вызов не ожидается, выполнение текущего метода продолжается до завершения вызова. Рассмотрите возможность применения
awaitоператора к результату вызова. - CS8177: асинхронные методы не могут иметь локальные переменные по ссылке.
-
CS9123: оператор '
&' не должен использоваться для параметров или локальных переменных в асинхронных методах. - CS4029: не удается вернуть выражение типа void.
- CS4030: атрибут безопасности нельзя применить к методу Async.
- CS4031: асинхронные методы не допускаются в интерфейсе, классе или структуре с атрибутом SecurityCritical или SecuritySafeCritical.
В следующих элементах объясняется, как исправить каждую ошибку. Дополнительные сведения см. в статье о программировании с async и await и об оператореawait.
- Добавьте оператор
awaitк каждому вызову, который возвращает Task или Task<TResult>, или явно игнорируйте результат с помощью_ =, если предполагается поведение типа fire-and-forget (CS4014). Безawait, любое исключение, вызванное асинхронной операцией, теряется без уведомления, и вызывающий метод продолжает выполняться до завершения операции, что может привести к тонким ошибкам упорядочения и корректности. -
returnУдалите выражение из асинхронного метода, возвращаемым типом которого являетсяTask(не универсальный), или измените возвращаемый тип наTask<T>, если методу необходимо вернуть значение (CS1997). В асинхронном методе, который возвращаетTask, компилятор создает оболочку задачи — возвращение значения приводит к несоответствию типа, потому что сигнатура метода не предполагает результат. - Добавьте хотя бы одно
awaitвыражение в текст метода или удалитеasyncмодификатор и верните задачу напрямую (CS1998). Методasync, не содержащий выраженийawait, выполняется полностью синхронно, что добавляет ненужные затраты на машину состояний. Если метод намеренно упаковывает синхронную операцию, удалениеasyncи возврат задачи явным образом устраняет эту нагрузку. - Перепишите лямбда-выражение так, чтобы не использовать
async, когда оно назначается типу дерева выражений, как в случаеExpression<Func<...>>CS1989. Деревья выражений представляют код как структуры данных, которые компилятор может анализировать или переводить, но сложный компьютер состояния, которыйasyncсоздает, не может быть записан в дереве выражений. - Измените реализацию события, чтобы объявление интерфейса и класс реализации согласились с тем, использует ли событие семантику среды выполнения Windows или обычную семантику .NET (CS1991). Эта ошибка применяется к сценариям взаимодействия среды выполнения Windows, где событие WinRT не может быть реализовано как обычное событие .NET или наоборот.
- Удалите адрес оператора (
&) из выражений, ссылающихся на параметры или локальные переменные внутри асинхронных методов (CS9123). Асинхронный компьютер состояния может переместить захваченные переменные в кучу во время приостановки, что приведет к недопустимости любого указателя, полученного через адрес. - Удалите передаваемые по ссылке локальные переменные из асинхронных методов или убедитесь, что они не охватывают границу
await(CS8177). Асинхронный компьютер состояния фиксирует локальные переменные в выделенном куче закрытии, а ссылки на расположения стека не могут быть безопасно сохранены в точках приостановки. В C# 13 и более позднихrefверсиях локальные переменные допускаются в асинхронных методах, если они не пересекаютawaitграницу, и эта ошибка не возникает. -
returnУдалите инструкцию, возвращающую результат методаvoid, который возвращает значение, или измените вызываемый метод, чтобы он возвращал значение (CS4029). Нельзя использоватьreturn SomeVoidMethod();, так какvoidне является типом, который можно вернуть в качестве значения. Удалите ключевоеreturnслово и вызовите метод как автономную инструкцию или измените сигнатуру вызываемого метода, чтобы вернуть конкретный тип. - Удалите атрибуты безопасности, например
[SecurityCritical]или[SecuritySafeCritical]из асинхронных методов (CS4030), или удалитеasyncмодификатор из методов в типах, помеченных этими атрибутами (CS4031). Аннотации безопасности доступа к коду применяются к объявляемому методу, но созданная компилятором асинхронная машина состояния выполняется в отдельном контексте, где эти аннотации безопасности не могут быть соблюдены.