前言:我在寻找一个解释,而不仅仅是一个解决方案。我已经知道了解决方案。
尽管花了几天时间研究有关基于任务的异步模式(TAP),异步和等待的MSDN文章,但我对某些更详细的信息仍然感到困惑。
我正在为Windows Store Apps编写记录器,并且希望同时支持异步和同步记录。异步方法遵循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死机?任务对象有问题吗?有没有明显的僵局?