【发布时间】:2013-01-07 06:01:34
【问题描述】:
前言:我正在寻找解释,而不仅仅是解决方案。我已经知道解决方案了。
尽管我花了几天时间研究有关基于任务的异步模式 (TAP)、async 和 await 的 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 导致冻结?任务对象有问题吗?是否存在不明显的死锁?
【问题讨论】:
-
运气好能在别处得到解释吗?下面的答案真的没有提供洞察力。我实际上使用的是 .net 4.0 而不是 4.5/5,所以我不能使用某些操作但遇到了同样的问题。
-
@amadib,ver.1 和 4 在 [rpvided answers 中进行了解释。 Ver.2 anв 3 尝试重新开始已经开始的任务。发布您的问题。目前尚不清楚如何在 .NET 4.0 上遇到 .NET 4.5 异步/等待问题
-
版本 4 是 Xamarin Forms 的最佳选择。我们尝试了其余的选项,但在所有情况下都没有成功并遇到死锁
-
谢谢!第 4 版对我有用。但它仍然异步运行吗?我假设是因为存在 async 关键字。
标签: c# .net task-parallel-library windows-store-apps async-await