首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >同步等待异步操作,为什么Wait()在这里冻结程序

同步等待异步操作,为什么Wait()在这里冻结程序
EN

Stack Overflow用户
提问于 2013-01-24 00:56:39
回答 5查看 128.3K关注 0票数 350

前言:我正在寻找一个解释,而不仅仅是一个解决方案。我已经知道解决方案了。

尽管我花了几天的时间研究了MSDN上关于基于任务的异步模式( Task-based Asynchronous Pattern,TAP)、异步模式和等待模式的文章,但我仍然对其中的一些细节感到困惑。

我正在为Windows应用商店应用编写一个记录器,我希望同时支持异步和同步日志记录。异步方法跟随TAP,同步方法应该隐藏所有这一切,并且看起来和工作起来都像普通方法。

这是异步日志记录的核心方法:

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
private void WriteToLog(string text)
{
    Task task = WriteToLogAsync(text);
    task.Wait();
}

这看起来是正确的,但它不起作用。整个程序永远冻结了。

版本2

嗯..。也许任务还没有开始?

代码语言:javascript
运行
复制
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听起来很有前途。

代码语言:javascript
运行
复制
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(解决方案):

代码语言:javascript
运行
复制
private void WriteToLog(string text)
{
    var task = Task.Run(async () => { await WriteToLogAsync(text); });
    task.Wait();
}

这是可行的。因此,2和3是错误的工具。但是1?1有什么问题,和4有什么区别?是什么使1导致冻结?任务对象有什么问题吗?是否存在不明显的死锁?

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14485115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档