序文:単なる解決策ではなく、説明を求めています。私はすでに解決策を知っています。
タスクベースの非同期パターン(TAP)、非同期、待機に関するMSDNの記事の調査に数日費やしましたが、細かい詳細についてはまだ混乱しています。
私はWindowsストアアプリ用のロガーを書いており、非同期と同期の両方のロギングをサポートしたいと考えています。非同期メソッドはTAPに従い、同期メソッドはこれをすべて隠す必要があり、通常のメソッドのように見え、機能します。
これは、非同期ロギングのコアメソッドです。
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);
}
今、対応する同期メソッド...
バージョン1:
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Wait();
}
これは正しいように見えますが、機能しません。プログラム全体が永久にフリーズします。
バージョン2:
うーん..タスクが開始されなかったのでしょうか?
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.Start();
task.Wait();
}
これは投げます InvalidOperationException: Start may not be called on a promise-style task.
バージョン3:
うーん.. Task.RunSynchronously
有望に聞こえます。
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.RunSynchronously();
}
これは投げます InvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
バージョン4(ソリューション):
private void WriteToLog(string text)
{
var task = Task.Run(async () => { await WriteToLogAsync(text); });
task.Wait();
}
これは機能します。したがって、2と3は間違ったツールです。しかし、1?1の何が問題で、4の違いは何ですか?何が1をフリーズさせるのですか?タスクオブジェクトに問題がありますか?非自明のデッドロックはありますか?