Поделиться через


Устранение ошибок и предупреждений в асинхронных методах с помощью оператора await

В этой статье рассматриваются следующие ошибки компилятора:

  • CS1983: так как это асинхронный метод, возвращаемое выражение должно иметь тип "Task<T>" вместо "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(...) "" для выполнения работы с ЦП на фоновом потоке.
  • CS4008: не удается ожидать "void".
  • CS4009: Точка входа, возвращающая void или int, не может быть асинхронной.
  • CS4014: так как этот вызов не ожидается, выполнение текущего метода продолжается до завершения вызова. Рассмотрите возможность применения await оператора к результату вызова.
  • CS4032: оператор 'await' может использоваться только в асинхронном методе. Рекомендуется пометить этот метод модификатором async и изменить тип возвращаемого значения на "Task<T>".
  • CS4033: оператор 'await' можно использовать только в асинхронном методе. Рекомендуется пометить этот метод модификатором "async" и изменить тип возвращаемого значения на "Task".
  • CS8892: метод не будет использоваться в качестве точки входа, так как обнаружена синхронная точка входа.
  • 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".

Чтобы правильно использовать await оператор, следуйте этим правилам. Дополнительные сведения см. в статье Асинхронное программирование с использованием async и await.

  • Не используйте await в предложениях catch (CS1985). Хотя вы можете использовать await в блоках try и finally (в C# 6 и более поздних версиях), блоки catch представляют собой особые проблемы с обработкой исключений и управлением потока.
  • Не используйте await внутри lock блоков инструкций (CS1996). Компилятор не поддерживает это, чтобы избежать создания кода, подверженного взаимоблокировкам.
  • Используйте await только в определенных местах в выражениях запросов (CS1995): в первом выражении коллекции исходного оператора from, или в выражении коллекции оператора join.
  • Пометьте методы или лямбда-выражения модификатором async перед использованием await (CS1992, CS4032, CS4033).
  • Убедитесь, что ожидаемые типы имеют доступный метод GetAwaiter, который возвращает тип ожидания (CS1986).
  • Не применяйте await к выражениям типа void (CS4008).
  • Измените тип возвращаемого значения на Task для методов, которые не возвращают значение, или на Task<T> для методов, которые возвращают значение.

Требования к подписи асинхронного метода

  • CS1983: так как это асинхронный метод, возвращаемое выражение должно иметь тип "Task<T>" вместо "T".
  • CS1994: Модификатор 'async' можно использовать только в методах, имеющих тело.
  • CS4009: Точка входа, возвращающая void или int, не может быть асинхронной.
  • CS8892: метод не будет использоваться в качестве точки входа, так как обнаружена синхронная точка входа.
  • CS9330: 'MethodImplAttribute.Async' нельзя применять вручную к методам. Пометьте метод 'async'.

Чтобы правильно объявить асинхронные методы, следуйте этим требованиям подписи. Дополнительные сведения см. в разделе Async main return values.

  • Верните один из допустимых типов: void, Task, Task<T>, похожий на задачу тип, IAsyncEnumerable<T>, или IAsyncEnumerator<T> (CS1983).
  • async Используйте модификатор только для методов с текстом (CS1994). async Удалите модификатор абстрактных методов в интерфейсах или классах.
  • Обновите до C# 7.1 или более поздней версии, чтобы использовать async в качестве Main точки входа, или избегайте использования async в точках входа в более ранних версиях (CS4009).
  • Удалите синхронные точки входа, если у вас есть точки синхронизации и асинхронного входа (CS8892).
  • Используйте ключевое async слово вместо применения MethodImplAttribute.Async вручную (CS9330).

Асинхронные методики

  • CS1989: асинхронные лямбда-выражения нельзя преобразовать в деревья выражений.
  • CS1991: "Тип" не может реализовать "событие", так как это событие среды выполнения Windows, и "событие" является обычным событием .NET.
  • CS1997: так как функция является асинхронным методом, возвращающим значение, ключевое слово возвращаемого значения не должно следовать выражению объекта.
  • CS1998: этот асинхронный метод не имеет операторов "await" и будет выполняться синхронно. Рассмотрите возможность использования оператора "await" для ожидания неблокирующих вызовов API илиawait Task.Run(...) "" для выполнения работы с ЦП на фоновом потоке.
  • CS4014: так как этот вызов не ожидается, выполнение текущего метода продолжается до завершения вызова. Рассмотрите возможность применения await оператора к результату вызова.
  • CS9123: оператор '&' не должен использоваться для параметров или локальных переменных в асинхронных методах.

Чтобы правильно написать асинхронный код и избежать распространенных ошибок, следуйте этим рекомендациям. Дополнительные сведения см. в статье Асинхронное программирование с использованием async и await.

  • Всегда ожидайте вызовы асинхронных методов, возвращающих Task или Task<TResult> (CS4014). Неожиданные вызовы могут привести к потере исключений и неожиданному поведению.
  • Не возвращайте значение из асинхронных методов, возвращающих Task (не универсальные); используйте Task<T> вместо этого (CS1997).
  • Включите по крайней мере один await оператор в асинхронные методы или удалите async модификатор (CS1998).
  • Удалите инструкцию return , если метод должен возвращать Task (CS1997, CS1998).
  • Измените тип возврата метода на Task<T>, чтобы он возвращал значение (CS1997, CS1998).
  • Удалите модификатор async и верните задачу непосредственно, если вам не нужен асинхронный автомат состояния (CS1997, CS1998).
  • Не используйте асинхронные методы в деревах выражений (CS1989). Деревья выражений представляют код как данные и не поддерживают преобразования сложной машины состояний, необходимые асинхронным методам.
  • Не отмечайте добавление или удаление методов доступа в интерфейсе или событии WinRT как асинхронное (CS1991). Это ограничение, специфичное для платформы, для взаимодействия с средой выполнения Windows.
  • Избегайте использования оператора адреса (&) для выражений внутри асинхронных методов (CS9123). Целевой объект может быть перемещен в памяти во время приостановки, что делает указатель недопустимым.