Baru saja mendapat VS2012 dan mencoba menangani async.
Katakanlah saya punya metode yang mengambil beberapa nilai dari sumber pemblokiran. Saya tidak ingin penelepon metode untuk memblokir. Saya bisa menulis metode untuk mengambil callback yang dipanggil ketika nilainya tiba, tetapi karena saya menggunakan C # 5, saya memutuskan untuk membuat metode async sehingga penelepon tidak harus berurusan dengan callback:
// contrived example (edited in response to Servy's comment)
public static Task<string> PromptForStringAsync(string prompt)
{
return Task.Factory.StartNew(() => {
Console.Write(prompt);
return Console.ReadLine();
});
}
Inilah contoh metode yang menyebutnya. Jika PromptForStringAsynctidak async, metode ini akan membutuhkan peneleponan kembali di dalam panggilan balik. Dengan async, saya bisa menulis metode saya dengan cara yang sangat alami ini:
public static async Task GetNameAsync()
{
string firstname = await PromptForStringAsync("Enter your first name: ");
Console.WriteLine("Welcome {0}.", firstname);
string lastname = await PromptForStringAsync("Enter your last name: ");
Console.WriteLine("Name saved as '{0} {1}'.", firstname, lastname);
}
Sejauh ini baik. Masalahnya adalah ketika saya memanggil GetNameAsync:
public static void DoStuff()
{
GetNameAsync();
MainWorkOfApplicationIDontWantBlocked();
}
Intinya GetNameAsyncadalah asinkron. Saya tidak ingin memblokir, karena saya ingin kembali ke MainWorkOfApplicationIDontWantBlocked ASAP dan biarkan GetNameAsync melakukan hal itu di latar belakang. Namun, menyebutnya dengan cara ini memberi saya peringatan kompiler di GetNameAsynctelepon:
Warning 1 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
Saya sangat menyadari bahwa "eksekusi metode saat ini berlanjut sebelum panggilan selesai". Itulah titik kode asynchronous, kan?
Saya lebih suka kode saya dikompilasi tanpa peringatan, tetapi tidak ada yang bisa "diperbaiki" di sini karena kode melakukan apa yang saya inginkan. Saya bisa menghilangkan peringatan dengan menyimpan nilai pengembalian GetNameAsync:
public static void DoStuff()
{
var result = GetNameAsync(); // supress warning
MainWorkOfApplicationIDontWantBlocked();
}
Tapi sekarang saya punya kode berlebihan. Visual Studio tampaknya mengerti bahwa saya dipaksa untuk menulis kode yang tidak perlu ini, karena menekan peringatan "nilai tidak pernah digunakan" yang normal.
Saya juga bisa menghilangkan peringatan dengan membungkus GetNameAsync dengan metode yang tidak async:
public static Task GetNameWrapper()
{
return GetNameAsync();
}
Tapi itu kode yang lebih berlebihan. Jadi saya harus menulis kode saya tidak perlu atau mentolerir peringatan yang tidak perlu.
Apakah ada sesuatu tentang penggunaan async yang salah di sini?
GetNameAsyncmemberikan nama lengkap yang disediakan oleh pengguna (yaitu Task<Name>, daripada hanya mengembalikan Task? DoStuffLalu dapat menyimpan tugas itu, dan apakah awaititu setelah metode lain, atau bahkan meneruskan tugas ke yang lain metode sehingga bisa awaitatau di Waitsuatu tempat di dalam implementasi itu
asynckata kunci.
PromptForStringAsyncAnda melakukan lebih banyak pekerjaan daripada yang Anda butuhkan; kembalikan saja hasilTask.Factory.StartNew. Sudah tugas siapa yang nilainya adalah string yang dimasukkan di konsol. Tidak perlu menunggu untuk mengembalikan hasilnya; hal itu tidak menambah nilai baru.