private void RunAsync()
{
string param = "Hi";
Task.Run(() => MethodWithParameter(param));
}
private void MethodWithParameter(string param)
{
}
Sunting
Karena permintaan yang populer, saya harus mencatat bahwa Taskpeluncuran akan berjalan secara paralel dengan utas panggilan. Dengan asumsi default TaskSchedulerini akan menggunakan .NET ThreadPool. Bagaimanapun, ini berarti Anda perlu memperhitungkan parameter apa pun yang diteruskan ke yang Taskberpotensi diakses oleh beberapa utas sekaligus, menjadikannya status bersama. Ini termasuk mengaksesnya di utas panggilan.
Dalam kode saya di atas kasus itu dibuat sepenuhnya diperdebatkan. String tidak bisa diubah. Itu sebabnya saya menggunakan mereka sebagai contoh. Tetapi katakanlah Anda tidak menggunakan String...
Salah satu solusinya adalah dengan menggunakan asyncdan await. Ini, secara default, akan menangkap SynchronizationContextthread pemanggil dan akan membuat kelanjutan untuk metode lainnya setelah panggilan ke awaitdan melampirkannya ke yang dibuat Task. Jika metode ini berjalan di utas WinForms GUI, itu akan menjadi tipe WindowsFormsSynchronizationContext.
Kelanjutan akan berjalan setelah diposting kembali ke yang ditangkap SynchronizationContext- lagi hanya secara default. Jadi Anda akan kembali ke utas yang Anda mulai setelah awaitpanggilan. Anda dapat mengubahnya dengan berbagai cara, terutama dengan menggunakan ConfigureAwait. Singkatnya, sisa metode yang tidak akan berlanjut sampai setelah yang Tasktelah diselesaikan pada thread lain. Tetapi utas panggilan akan terus berjalan secara paralel, tidak hanya seluruh metode.
Penantian untuk menyelesaikan menjalankan sisa metode ini mungkin diinginkan atau tidak diinginkan. Jika tidak ada dalam metode itu nanti yang mengakses parameter yang diteruskan ke TaskAnda mungkin tidak ingin menggunakan awaitsama sekali.
Atau mungkin Anda menggunakan parameter tersebut nanti dalam metode. Tidak ada alasan untuk awaitsegera karena Anda bisa terus melakukan pekerjaan dengan aman. Ingat, Anda bisa menyimpan yang Taskdikembalikan dalam variabel dan awaitnanti - bahkan dalam metode yang sama. Misalnya, setelah Anda perlu mengakses parameter yang diteruskan dengan aman setelah melakukan banyak pekerjaan lain. Sekali lagi, Anda tidak perlu awaitdi Taskkanan saat Anda menjalankannya.
Bagaimanapun, cara sederhana untuk membuat thread ini aman sehubungan dengan parameter yang diteruskan Task.Runadalah dengan melakukan ini:
Anda harus terlebih dahulu mendekorasi RunAsyncdengan async:
private async void RunAsync()
Catatan penting
Lebih disukai metode yang ditandai tidak boleh kembali kosong, seperti yang disebutkan dalam dokumentasi terkait. Pengecualian umum untuk ini adalah pengendali kejadian seperti klik tombol dan semacamnya. Mereka harus mengembalikan kekosongan. Kalau tidak, saya selalu mencoba mengembalikan atau saat menggunakan . Ini praktik yang baik karena beberapa alasan.async TaskTask<TResult>async
Sekarang Anda dapat awaitmenjalankan Taskseperti di bawah ini. Anda tidak dapat menggunakan awaittanpa async.
await Task.Run(() => MethodWithParameter(param));
Jadi, secara umum, jika Anda awaitmelakukan tugas tersebut, Anda dapat menghindari memperlakukan parameter yang diteruskan sebagai sumber daya yang berpotensi dibagikan dengan semua perangkap memodifikasi sesuatu dari beberapa utas sekaligus. Juga, waspadalah terhadap penutupan . Saya tidak akan membahasnya secara mendalam tetapi artikel terkait melakukan pekerjaan dengan baik.
Catatan Samping
Sedikit keluar dari topik, tapi hati-hati menggunakan semua jenis "pemblokiran" pada utas GUI WinForms karena itu ditandai dengan [STAThread]. Penggunaan awaittidak akan memblokir sama sekali, tetapi terkadang saya melihatnya digunakan sehubungan dengan semacam pemblokiran.
"Blokir" ada dalam tanda kutip karena Anda secara teknis tidak dapat memblokir utas GUI WinForms . Ya, jika Anda menggunakan lockpada utas GUI WinForms, ia masih akan memompa pesan, meskipun Anda mengira itu "diblokir". Ini bukan.
Ini dapat menyebabkan masalah aneh dalam kasus yang sangat jarang terjadi. Salah satu alasan Anda tidak ingin menggunakan locksaat melukis, misalnya. Tapi itu kasus pinggiran dan kompleks; Namun saya telah melihatnya menyebabkan masalah gila. Jadi saya mencatatnya demi kelengkapan.