呼叫等待GetFileAsync()永远不会返回,并在应用程序WinRT中挂起 [英] Call to await GetFileAsync() never returns and app hangs in WinRT app

查看:167
本文介绍了呼叫等待GetFileAsync()永远不会返回,并在应用程序WinRT中挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图加载和读取设置在应用程序启动文件,时间大约90%,在等待GetFileAsync(filename.xml中); 永远不会返回,因此,挂的应用程序。

I'm attempting to load and read a settings file on application launch, and about 90% of the time, the await GetFileAsync("filename.xml"); never returns, thus, hanging the application.

关于有四分之一的时间,如果我通过code步骤,它会返回实际上并读取该文件。

About a quarter of the time, if I step through the code, it'll actually return and read the file.

这里的code的一个简化版本:

Here's a very simplified version of the code:

App.xaml.cs:

App.xaml.cs:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    FileLoader.Load().Wait();

    // File-load dependent stuff
}

FileLoader.cs:

FileLoader.cs:

public async static Task Load()
{
    StorageFolder folder = ApplicationData.Current.LocalFolder;
    StorageFile file;
    bool fileExists = true;

    try
    {
        // The following line (often) never returns
        file = await folder.GetFileAsync("filename.xml");
    {
    catch
    {
        fileExists = false;
    }

    // Do stuff with loaded file
}

如果我看在Visual Studio Output窗口,经过一段时间的等待,我得到线程'<没有名称>' (0x30c)已退出与code 0(为0x0)。

If I watch the Output window in Visual Studio, after awhile of waiting I get "The thread '<No Name>' (0x30c) has exited with code 0 (0x0)."

有没有人有这里发生了什么的任何想法?

Does anyone have any idea of what's happening here?

推荐答案

在默认情况下,当你的await A 工作一个尚未完成,则该方法继续在捕获的上下文(在这种情况下,在UI上下文)。

By default, when you await a Task that has not yet completed, the method resumes on a captured context (in this case, the UI context).

所以,在这里就是为什么你的code失败:

So, here's why your code is failing:


  • OnLaunched 要求加载(用户界面范围内)。

  • 加载等待。这将导致加载方法返回一个不完整的任务,并计划建成供以后使用。这延续定于UI环境。

  • 在任务
  • OnLaunched 阻止加载返回。这将阻止UI线程。

  • GetFileAsync 最终完成,并尝试运行加载的延续。

  • 加载的继续等待UI线程可用,因此它可以在UI上下文中执行的。

  • 在这一点上,<​​code> OnLaunched 正在载入等来完成(这样做阻塞UI线程)和加载正在等待UI线程是免费的。僵局。

  • OnLaunched calls Load (within the UI context).
  • Load awaits. This causes the Load method to return an incomplete task and schedule its completion for later. This continuation is scheduled for the UI context.
  • OnLaunched blocks on the task returned from Load. This blocks the UI thread.
  • GetFileAsync eventually completes, and attempts to run the continuation for Load.
  • The continuation for Load waits for the UI thread to be available so it can execute in the UI context.
  • At this point, OnLaunched is waiting for Load to complete (blocking the UI thread by doing so), and Load is waiting for the UI thread to be free. Deadlock.

这些最佳实践避免出现这种情况:

These best practices avoid this situation:


  1. 在库异步方法,使用 ConfigureAwait(假)只要有可能。在你的情况,这将改变等待folder.GetFileAsync(filename.xml中); 等待folder.GetFileAsync(filename.xml中) .ConfigureAwait(假);

  2. 请不要在工作 S挡;这是异步一路下跌。换句话说,替换等待等待

  1. In your "library" async methods, use ConfigureAwait(false) whenever possible. In your case, this would change await folder.GetFileAsync("filename.xml"); to await folder.GetFileAsync("filename.xml").ConfigureAwait(false);.
  2. Don't block on Tasks; it's async all the way down. In other words, replace Wait with await.

有关详细信息:


  • 等待和UI,和死锁!哦,我的!

  • 我的<一个href=\"http://nitoprograms.blogspot.com/2012/02/async-and-await.html\"><$c$c>async/<$c$c>await介绍后,其中包括工作 awaiters如何使用的SynchronizationContext 的简要说明,并介绍了一些最佳实践。

  • /等待FAQ ,该进入详细在上下文中。

  • 这<一个href=\"http://social.msdn.microsoft.com/Forums/en-AU/async/thread/269172a3-adb9-4b5e-9ac1-8b67ff920177\">MSDN论坛帖子。

  • 斯蒂芬Toub 演示这一僵局和<一个href=\"http://blogs.msdn.com/b/lucian/archive/2012/03/29/talk-async-part-1-the-message-loop-and-the-task-type.aspx\">so确实卢西恩Wischik 。

  • Await, and UI, and deadlocks! Oh, my!
  • My async/await intro post, which includes a brief description of how Task awaiters use SynchronizationContext and introduces some best practices.
  • The Async/Await FAQ, which goes into more detail on the contexts.
  • This MSDN forum post.
  • Stephen Toub demos this deadlock, and so does Lucian Wischik.

更新,2012-07-13:将这一答案的成博客文章

这篇关于呼叫等待GetFileAsync()永远不会返回,并在应用程序WinRT中挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆