Pertama, mari kita jelaskan beberapa terminologi: "asynchronous" ( async
) berarti bahwa ia dapat menghasilkan kontrol kembali ke utas panggilan sebelum dimulai. Dalam suatu async
metode, titik "hasil" itu adalah await
ekspresi.
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, async
sangat berbeda dari "ditunggu"; ada beberapa async
metode 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
async
kunci memungkinkan metode asinkron (yaitu, memungkinkan await
ekspresi). async
metode 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
Task
dan 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 async
metode yang dapat menghasilkan kembali ke pemanggilnya alih-alih memblokir", jawabannya adalah untuk mendeklarasikan metode async
dan gunakan await
untuk 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 async
kode bergantung pada "yang dapat ditunggu" dalam await
ekspresi. "Barang yang bisa ditunggu-tunggu" ini bisa berupa async
metode lain atau hanya metode biasa untuk mengembalikan barang yang bisa ditunggu. Metode biasa kembali Task
/ Task<T>
dapat menggunakan Task.Run
untuk 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
/ await
intro di blog saya; pada akhirnya adalah beberapa sumber daya tindak lanjut yang baik. Dokumen MSDN async
juga luar biasa bagus.