Bagikan melalui


Mengatasi kesalahan dan peringatan dalam metode asinkron menggunakan operator tunggu

Artikel ini membahas kesalahan pengkompilasi berikut:

  • CS1983: Karena ini adalah metode asinkron, ekspresi pengembalian harus berjenis 'Task<T>' daripada 'T'.
  • CS1985: Tidak dapat menggunakan 'await' dalam klausa catch.
  • CS1986: 'await' mengharuskan jenis memiliki metode 'GetAwaiter'yang cocok.
  • CS1989: Ekspresi lambda asinkron tidak dapat dikonversi ke pohon ekspresi.
  • CS1991: 'Type' tidak dapat menerapkan 'event' karena merupakan peristiwa Windows Runtime dan 'event' adalah peristiwa .NET biasa.
  • CS1992: Operator 'await' hanya dapat digunakan saat dimuat dalam metode atau ekspresi lambda yang ditandai dengan pengubah 'asinkron'.
  • CS1994: Pengubah 'async' hanya dapat digunakan dalam metode yang memiliki tubuh.
  • CS1995: Operator 'await' hanya dapat digunakan dalam ekspresi kueri dalam ekspresi koleksi pertama dari klausa 'from' awal atau dalam ekspresi koleksi klausa ''join.
  • CS1996: Tidak dapat menunggu dalam isi pernyataan kunci.
  • CS1997: Karena fungsi adalah metode asinkron yang mengembalikan nilai, kata kunci pengembalian tidak boleh diikuti oleh ekspresi objek.
  • CS1998: Metode asinkron ini tidak memiliki operator 'await' dan akan berjalan secara sinkron. Pertimbangkan untuk menggunakan operator 'await' untuk menunggu panggilan API non-pemblokiran, atau 'await Task.Run(...)' untuk melakukan pekerjaan terikat CPU pada utas latar belakang.
  • CS4008: Tidak dapat menunggu 'void'.
  • CS4009: Titik masuk yang mengembalikan void atau int tidak dapat asinkron.
  • CS4014: Karena panggilan ini tidak ditunggu, eksekusi metode saat ini berlanjut sebelum panggilan selesai. Pertimbangkan untuk menerapkan await operator ke hasil panggilan.
  • CS4032: Operator 'await' hanya dapat digunakan dalam metode asinkron. Pertimbangkan untuk menandai metode ini dengan pengubah 'asinkron' dan mengubah jenis pengembaliannya menjadi 'Task<T>'.
  • CS4033: Operator 'await' hanya dapat digunakan dalam metode asinkron. Pertimbangkan untuk menandai metode ini dengan pengubah 'async' dan mengubah jenis pengembaliannya menjadi 'Task'.
  • CS8892: Metode tidak akan digunakan sebagai titik masuk karena titik masuk sinkron ditemukan.
  • CS9123: Operator '&' tidak boleh digunakan pada parameter atau variabel lokal dalam metode asinkron.
  • CS9330: 'MethodImplAttribute.Async' tidak dapat diterapkan secara manual ke metode. Tandai metode 'asinkron'.

Menunggu persyaratan ekspresi

  • CS1985: Tidak dapat menggunakan 'await' dalam klausa catch.
  • CS1986: 'await' mengharuskan jenis memiliki metode 'GetAwaiter'yang cocok.
  • CS1992: Operator 'await' hanya dapat digunakan saat terkandung dalam metode atau ekspresi lambda yang ditandai dengan pengubah ''async.
  • CS1995: Operator 'await' hanya dapat digunakan dalam ekspresi kueri, yaitu dalam ekspresi koleksi pertama dari klausa 'from' awal atau dalam ekspresi koleksi dari klausa 'join'.
  • CS1996: Tidak dapat menunggu dalam isi pernyataan kunci.
  • CS4008: Tidak dapat menunggu 'void'.
  • CS4032: Operator 'await' hanya dapat digunakan dalam metode asinkron. Pertimbangkan untuk menandai metode ini dengan pengubah 'async' dan mengubah jenis pengembaliannya menjadi 'Task<T>'.
  • CS4033: Operator 'await' hanya dapat digunakan dalam metode asinkron. Pertimbangkan untuk menandai metode ini dengan pengubah 'async' dan mengubah jenis pengembaliannya menjadi 'Task'.

Untuk menggunakan await operator dengan benar, ikuti aturan ini. Untuk informasi selengkapnya, lihat Pemrograman asinkron dengan asinkron dan tunggu.

  • Jangan gunakan await dalam klausul tangkapan (CS1985). Meskipun Anda dapat menggunakan await dalam blok percobaan dan blok akhirnya (di C# 6 dan yang lebih baru), blok catch menghadirkan tantangan khusus dalam penanganan pengecualian dan alur kontrol.
  • Jangan gunakan await di dalam blok pernyataan lock (CS1996). Pengkompilasi tidak mendukung ini untuk menghindari memancarkan kode yang rentan terhadap kebuntuan.
  • Gunakan await hanya di lokasi tertentu dalam ekspresi kueri (CS1995): di dalam ekspresi koleksi pertama dari klausa awal from, atau dalam koleksi ekspresi dari klausa join.
  • Tandai metode atau ekspresi lambda dengan pengubah async sebelum menggunakan await (CS1992, CS4032, CS4033).
  • Pastikan jenis yang ditunggu memiliki metode yang dapat diakses GetAwaiter yang mengembalikan tipe penunggu (CS1986).
  • Jangan menerapkan await pada ekspresi tipe void (CS4008).
  • Ubah jenis pengembalian menjadi Task untuk metode yang tidak mengembalikan nilai, atau Task<T> untuk metode yang mengembalikan nilai.

Persyaratan tanda tangan metode asinkron

  • CS1983: Karena ini adalah metode asinkron, ekspresi pengembalian harus berjenis 'Task<T>' daripada 'T'.
  • CS1994: Pengubah 'async' hanya dapat digunakan dalam metode yang memiliki tubuh.
  • CS4009: Titik masuk yang void atau mengembalikan int tidak bisa asinkron.
  • CS8892: Metode tidak akan digunakan sebagai titik masuk karena titik masuk sinkron ditemukan.
  • CS9330: 'MethodImplAttribute.Async' tidak dapat diterapkan secara manual ke metode. Tandai metode 'async'.

Untuk mendeklarasikan metode asinkron dengan benar, ikuti persyaratan tanda tangan ini. Untuk informasi selengkapnya, lihat Nilai pengembalian utama asinkron.

  • Mengembalikan salah satu jenis yang valid: void, Task, Task<T>, jenis seperti tugas, IAsyncEnumerable<T>, atau IAsyncEnumerator<T> (CS1983).
  • Gunakan pengubah async hanya pada metode dengan isi (CS1994). Hapus pengubah async pada metode abstrak di antarmuka atau kelas.
  • Perbarui ke C# 7.1 atau yang lebih tinggi untuk digunakan async pada Main titik masuk, atau hindari penggunaan async pada titik masuk dalam versi sebelumnya (CS4009).
  • Hapus titik masuk sinkron jika Anda memiliki titik masuk sinkronisasi dan asinkron (CS8892).
  • async Gunakan kata kunci alih-alih menerapkan MethodImplAttribute.Async secara manual (CS9330).

Praktik asinkron

  • CS1989: Ekspresi lambda asinkron tidak dapat dikonversi ke pohon ekspresi.
  • CS1991: 'Type' tidak dapat menerapkan 'event' karena merupakan peristiwa Windows Runtime dan 'event' adalah peristiwa .NET biasa.
  • CS1997: Karena fungsi adalah metode asinkron yang mengembalikan nilai, kata kunci pengembalian tidak boleh diikuti oleh ekspresi objek.
  • CS1998: Metode asinkron ini tidak memiliki operator 'await' dan akan berjalan secara sinkron. Pertimbangkan untuk menggunakan operator 'await' untuk menunggu panggilan API non-pemblokiran, atau 'await Task.Run(...)' untuk melakukan pekerjaan terikat CPU pada utas latar belakang.
  • CS4014: Karena panggilan ini tidak ditunggu, eksekusi metode saat ini berlanjut sebelum panggilan selesai. Pertimbangkan untuk menerapkan await operator ke hasil panggilan.
  • CS9123: Operator '&' tidak boleh digunakan pada parameter atau variabel lokal dalam metode asinkron.

Untuk menulis kode asinkron dengan benar dan menghindari jebakan umum, ikuti praktik terbaik ini. Untuk informasi selengkapnya, lihat Pemrograman asinkron dengan asinkron dan tunggu.

  • Selalu tunggu panggilan ke metode asinkron yang mengembalikan Task atau Task<TResult> (CS4014). Panggilan yang tidak diawasi dapat menyebabkan hilangnya pengecualian dan perilaku tak terduga.
  • Jangan mengembalikan nilai dari metode asinkron yang mengembalikan Task (non-generik); gunakan Task<T> sebagai gantinya (CS1997).
  • Sertakan setidaknya satu await operator dalam metode asinkron, atau hapus pengubah async (CS1998).
  • return Hapus pernyataan jika metode harus mengembalikan Task (CS1997, CS1998).
  • Ubah jenis pengembalian metode menjadi Task<T> untuk mengembalikan nilai (CS1997, CS1998).
  • Hapus pengubah async dan kembalikan tugas secara langsung jika Anda tidak memerlukan mesin status asinkron (CS1997, CS1998).
  • Jangan gunakan metode asinkron di pohon ekspresi (CS1989). Pohon ekspresi mewakili kode sebagai data dan tidak mendukung transformasi komputer status kompleks yang diperlukan oleh metode asinkron.
  • Jangan tandai tambahkan atau hapus aksesor di antarmuka atau peristiwa WinRT sebagai asinkron (CS1991). Ini adalah pembatasan khusus platform untuk interoperabilitas Windows Runtime.
  • Hindari menggunakan alamat operator (&) pada ekspresi di dalam metode asinkron (CS9123). Target dapat direlokasi dalam memori selama penangguhan, membuat pointer tidak valid.