Amalan terbaik dalam pengaturcaraan tidak segerak

Pengaturcaraan tak segerak membolehkan anda melakukan operasi I / O intensif sumber tanpa perlu menyekat utama atau utas pelaksanaan aplikasi. Walaupun bermanfaat dan nampaknya mudah dilaksanakan, ia mempunyai banyak kerumitan dan risiko. Potensi risiko yang berkaitan dengan pengaturcaraan async, terutamanya menggunakan pengaturcaraan tak segerak dengan cara yang salah dengan tidak mengikuti amalan yang disyorkan, termasuk kebuntuan, kerosakan proses dan juga prestasi yang perlahan. Anda juga harus mahir menulis, menyahpepijat kod asinkron.

Elakkan mempunyai jenis pengembalian yang tidak sah dalam kaedah async

Kaedah dalam C # dibuat kaedah tidak segerak menggunakan kata kunci asinkron dalam kaedah tandatangan. Anda boleh mempunyai satu atau lebih kata kunci menunggu dalam kaedah async. Kata kunci tunggu tunggu digunakan untuk menunjukkan titik penggantungan. Kaedah async di C # boleh mempunyai salah satu daripada jenis pengembalian ini: Tugas, Tugas dan batal. Kata kunci "tunggu" digunakan dalam kaedah async untuk memberitahu penyusun bahawa kaedah tersebut boleh mempunyai titik penggantungan dan penyambungan semula.

Perhatikan bahawa semasa menggunakan TPL, setara dengan pengembalian kekosongan dalam TPL adalah Tugas tidak segerak. Anda harus sedar bahawa async void adalah dan hanya boleh digunakan untuk acara async. Sekiranya anda menggunakannya di tempat lain, anda akan mengalami kesilapan. Dengan kata lain, kaedah async yang tidak sah sebagai jenis pengembalian tidak digalakkan. kerana kaedah async yang mengembalikan kekosongan mempunyai semantik yang berbeza ketika anda bekerja dengan pengecualian dalam aplikasi anda.

Apabila pengecualian berlaku dalam kaedah async yang mempunyai jenis kembali tugas atau tugas, objek pengecualian disimpan di dalam objek tugas. Sebaliknya, jika anda mempunyai kaedah async dengan jenis kekosongan kembali, tidak ada objek Tugas yang berkaitan. Pengecualian seperti itu dibangkitkan pada SynchronizationContext yang aktif pada masa kaedah asynchronous dipanggil. Dengan kata lain, anda tidak dapat menangani pengecualian yang dikemukakan dalam kaedah tidak sah async menggunakan pengendali pengecualian yang ditulis di dalam kaedah tidak segerak. Kaedah async yang mempunyai jenis kekosongan pengembalian juga sukar diuji kerana perbezaan ini dalam semantik pengendalian ralat. Untuk makluman anda, kelas SynchronizationContext di System. Threading namespace mewakili konteks penyegerakan di. Net dan membantu anda mengantri tugas ke konteks lain.

Penyenaraian kod berikut menggambarkan ini. Anda mempunyai dua kaedah iaitu, Test dan TestAsync dan yang terakhir membuang pengecualian.

public class AsyncDemo

   {

       public void Test()

       {

           try

           {

               TestAsync();

           }

           catch (Exception ex)

           {

               Console.WriteLine(ex.Message);

           }

       }

       private async void TestAsync()

       {

           throw new Exception("This is an error message");

       }

   }

Inilah cara anda dapat membuat contoh kelas AsyncDemo dan menggunakan kaedah Uji.

static void Main(string[] args)

       {

           AsyncDemo obj = new AsyncDemo();

           obj.Test();

           Console.Read();

       }

Kaedah ujian membuat panggilan ke kaedah TestAsync dan panggilan dibungkus di dalam blok cubaan tangkapan dengan tujuan menangani pengecualian yang dilemparkan di dalam kaedah TestAsync. Walau bagaimanapun, pengecualian yang dilemparkan di dalam kaedah TestAsync tidak akan dapat ditangkap, iaitu, dikendalikan di dalam kaedah pemanggil Uji.

Elakkan mencampurkan kod tak segerak dan segerak

Anda tidak semestinya mempunyai gabungan kod segerak dan tak segerak. Amalan pengaturcaraan yang buruk untuk menyekat kod async dengan membuat panggilan ke Task.Wait atau Task.Result. Saya akan mengesyorkan menggunakan kod async dari ujung ke ujung - ini adalah kaedah paling selamat untuk mengelakkan kesalahan daripada masuk.

Anda boleh mengelakkan kebuntuan dengan menggunakan. ConfigureAwait(continueOnCapturedContext: false)setiap kali anda membuat panggilan untuk menunggu. Sekiranya anda tidak menggunakan ini, kaedah async akan menyekat pada saat menunggu menunggu dipanggil. Dalam kes ini, anda hanya memberitahu pelayan untuk tidak menangkap konteks semasa. Saya akan mengatakan bahawa adalah amalan yang baik untuk menggunakan. ConfigureAwait (false) melainkan anda mempunyai alasan tertentu untuk tidak menggunakannya.

Saya akan membincangkan lebih lanjut mengenai pengaturcaraan tak segerak dalam catatan blog saya di masa depan di sini. Untuk maklumat lebih lanjut mengenai amalan terbaik dalam pengaturcaraan tak segerak, anda boleh merujuk artikel hebat Stephen Cleary di MSDN.