Pertama, mari kita jelaskan beberapa terminologi: "asynchronous" ( async) berarti bahwa ia dapat menghasilkan kontrol kembali ke utas panggilan sebelum dimulai. Dalam suatu asyncmetode, titik "hasil" itu adalah awaitekspresi.
Ini sangat berbeda dari istilah "asinkron", seperti (mis) yang digunakan oleh dokumentasi MSDN selama bertahun-tahun yang berarti "dieksekusi di utas latar belakang".
Lebih lanjut membingungkan masalah, asyncsangat berbeda dari "ditunggu"; ada beberapa asyncmetode yang jenis pengembaliannya tidak menunggu, dan banyak metode mengembalikan jenis yang ditunggu tidak async.
Cukup tentang apa yang bukan mereka ; inilah yang mereka adalah :
- Kata
asynckunci memungkinkan metode asinkron (yaitu, memungkinkan awaitekspresi). asyncmetode dapat kembali Task,, Task<T>atau (jika Anda harus) void.
- Jenis apa pun yang mengikuti pola tertentu dapat ditunggu. Jenis yang paling umum ditunggu adalah
Taskdan Task<T>.
Jadi, jika kami merumuskan kembali pertanyaan Anda ke "bagaimana saya bisa menjalankan operasi pada utas latar belakang dengan cara yang bisa ditunggu", jawabannya adalah menggunakan Task.Run:
private Task<int> DoWorkAsync() // No async because the method does not need await
{
return Task.Run(() =>
{
return 1 + 2;
});
}
(Tetapi pola ini adalah pendekatan yang buruk; lihat di bawah).
Tetapi jika pertanyaan Anda adalah "bagaimana cara membuat asyncmetode yang dapat menghasilkan kembali ke pemanggilnya alih-alih memblokir", jawabannya adalah untuk mendeklarasikan metode asyncdan gunakan awaituntuk poin "menghasilkan":
private async Task<int> GetWebPageHtmlSizeAsync()
{
var client = new HttpClient();
var html = await client.GetAsync("http://www.example.com/");
return html.Length;
}
Jadi, pola dasar segala sesuatu adalah memiliki asynckode bergantung pada "yang dapat ditunggu" dalam awaitekspresi. "Barang yang bisa ditunggu-tunggu" ini bisa berupa asyncmetode lain atau hanya metode biasa untuk mengembalikan barang yang bisa ditunggu. Metode biasa kembali Task/ Task<T> dapat menggunakan Task.Rununtuk mengeksekusi kode di thread latar belakang, atau (lebih umum) mereka dapat menggunakan TaskCompletionSource<T>atau salah satu cara pintas nya ( TaskFactory.FromAsync, Task.FromResult, dll). Saya tidak merekomendasikan membungkus seluruh metode di Task.Run; Metode sinkron harus memiliki tanda tangan sinkron, dan harus diserahkan kepada konsumen apakah harus dibungkus dengan Task.Run:
private int DoWork()
{
return 1 + 2;
}
private void MoreSynchronousProcessing()
{
// Execute it directly (synchronously), since we are also a synchronous method.
var result = DoWork();
...
}
private async Task DoVariousThingsFromTheUIThreadAsync()
{
// I have a bunch of async work to do, and I am executed on the UI thread.
var result = await Task.Run(() => DoWork());
...
}
Saya memiliki async/ awaitintro di blog saya; pada akhirnya adalah beberapa sumber daya tindak lanjut yang baik. Dokumen MSDN asyncjuga luar biasa bagus.