前言:我寻求的是一个解释,而不仅仅是一个解决方案。我已经知道解了。
尽管花了几天时间研究MSDN上关于基于任务的异步模式(TAP)、async和await的文章,但我仍然对一些更精细的细节感到困惑。
我正在为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:在promise类型的任务上不能调用Start。
版本3:
嗯. .的任务。runsynchrontically听起来很有希望。
private void WriteToLog(string text)
{
Task task = WriteToLogAsync(text);
task.RunSynchronously();
}
这将引发InvalidOperationException:对于未绑定到委托的任务,例如异步方法返回的任务,不能调用runsynchronically。
版本4(解决方案):
private void WriteToLog(string text)
{
var task = Task.Run(async () => { await WriteToLogAsync(text); });
task.Wait();
}
这个作品。所以,2和3是错误的工具。但1 ?1和4有什么不同?是什么导致1结冰?任务对象是否有问题?是否存在不明显的死锁?