gpt4 book ai didi

c# - 调用 await GetFileAsync() 永远不会返回并且应用程序在 WinRT 应用程序中挂起

转载 作者:IT王子 更新时间:2023-10-29 04:18:24 26 4
gpt4 key购买 nike

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

大约四分之一的时间,如果我单步执行代码,它实际上会返回并读取文件。

这是代码的一个非常简化的版本:

App.xaml.cs:

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

// File-load dependent stuff
}

文件加载器.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 中查看“输出”窗口,等待一段时间后我会得到 "The thread '<No Name>' (0x30c) has exited with code 0 (0x0)."

有人知道这里发生了什么吗?

最佳答案

默认情况下,当您await 尚未完成的Task 时,该方法会在捕获的上下文(在本例中为 UI 上下文)上恢复。

所以,这就是您的代码失败的原因:

  • OnLaunched 调用 Load(在 UI 上下文中)。
  • 加载 正在等待。这会导致 Load 方法返回一个未完成的任务并安排它在以后完成。此延续计划用于 UI 上下文。
  • OnLaunched 阻止从 Load 返回的任务。这会阻塞 UI 线程。
  • GetFileAsync 最终完成,并尝试运行 Load 的延续。
  • Load 的延续等待 UI 线程可用,以便它可以在 UI 上下文中执行。
  • 此时,OnLaunched 正在等待 Load 完成(这样做会阻塞 UI 线程),Load 正在等待UI线程是免费的。死锁。

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

  1. 在您的“库”async 方法中,尽可能使用ConfigureAwait(false)。在您的情况下,这会将 await folder.GetFileAsync("filename.xml"); 更改为 await folder.GetFileAsync("filename.xml").ConfigureAwait(false);.
  2. 不要阻塞任务;它一直都是 async。换句话说,将 Wait 替换为 await

更多信息:

更新,2012-07-13:合并了这个答案 into a blog post .

关于c# - 调用 await GetFileAsync() 永远不会返回并且应用程序在 WinRT 应用程序中挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11316438/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com