Pendahuluan : Saya mencari penjelasan, bukan hanya solusi. Saya sudah tahu solusinya.
Meskipun telah menghabiskan beberapa hari mempelajari artikel MSDN tentang Asynchronous Pattern (TAP) berbasis Tugas, async dan menunggu, saya masih agak bingung tentang beberapa detail yang lebih baik.
Saya sedang menulis logger untuk Aplikasi Windows Store, dan saya ingin mendukung logging asinkron dan sinkron. Metode asinkron mengikuti TAP, yang sinkron harus menyembunyikan semua ini, dan terlihat dan berfungsi seperti metode biasa.
Ini adalah metode inti pencatatan asinkron:
private async Task WriteToLogAsync(string text)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync("log.log",
CreationCollisionOption.OpenIfExists);
await FileIO.AppendTextAsync(file, text,
Windows.Storage.Streams.UnicodeEncoding.Utf8);
}
Sekarang metode sinkron yang sesuai ...
Versi 1 :
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Wait();
}
Ini terlihat benar, tetapi tidak berhasil. Seluruh program membeku selamanya.
Versi 2 :
Hmm .. Mungkin tugasnya belum dimulai?
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Start();
task.Wait();
}
Ini melempar InvalidOperationException: Start may not be called on a promise-style task.
Versi 3:
Hmm .. Task.RunSynchronously
kedengarannya menjanjikan.
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.RunSynchronously();
}
Ini melempar InvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
Versi 4 (solusinya):
private void WriteToLog(string text)
{
var task = Task.Run(async () => { await WriteToLogAsync(text); });
task.Wait();
}
Ini bekerja. Jadi, 2 dan 3 adalah alat yang salah. Tapi 1? Apa yang salah dengan 1 dan apa bedanya dengan 4? Apa yang membuat saya membeku? Apakah ada masalah dengan objek tugas? Apakah ada jalan buntu yang tidak jelas?