【问题标题】:StorageFolder.GetFilesAsync() freezes UWP and WinRT app [duplicate]StorageFolder.GetFilesAsync() 冻结 UWP 和 WinRT 应用程序 [重复]
【发布时间】:2017-09-20 15:51:49
【问题描述】:

我正在尝试将 xml 配置文件从安装目录移动到本地目录。当它到达 StorageFolder.GetFilesAsync() 时,它会冻结应用程序并且永远不会恢复。

我正在调用的代码位于 Windows RT 项目中,因此我无法在公共方法中使其异步。如果我将客户端 UWP 应用程序方法设为异步调用,似乎没有什么区别。

private async void InstallButton_Click(object sender, RoutedEventArgs e)
{
    await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        bool installed = FileManager.Install(StorageLocation.Local);
    });

}

public static bool Install(StorageLocation location)
{
    return InstallAsync(location).Result;
}  

private static async Task<bool> InstallAsync(StorageLocation location)
{
    try
    {
        StorageFolder destinationFolder = null;
        if (location == StorageLocation.Local)
        {
            destinationFolder = ApplicationData.Current.LocalFolder;
        }
        else if (location == StorageLocation.Roaming)
        {
            destinationFolder = ApplicationData.Current.RoamingFolder;
        }

        if (destinationFolder == null)
        {
            return false;
        }

        StorageFolder folder = Package.Current.InstalledLocation;
        if (folder == null)
        {
            return false;
        }

        // Language files are installed in a sub directory
        StorageFolder subfolder = await folder.GetFolderAsync(languageDirectory);
        if (subfolder == null)
        {
            return false;
        }

        // Get a list of files

        IReadOnlyList<StorageFile> files = await subfolder.GetFilesAsync();

        foreach (StorageFile file in files)
        {
            if (file.Name.EndsWith(".xml"))
            {
                await file.CopyAsync(destinationFolder);
            }
        }
    }
    catch (Exception)
    { }

    return IsInstalled(location);
}

【问题讨论】:

  • 尝试在您的按钮点击中调用await FileManager.InstallAsync(StorageLocation.Local);,而不是等待它。不要让异步代码同步运行 - 您也可以在 Stephen Cleary's blog 阅读有关死锁的信息。另一件事 - IsInstalled(location) 是什么? - 它是另一种同步等待异步代码的方法(如.Result)?
  • 另一个问题 - 为什么你在 Distpatcher 上运行它?

标签: c# windows-runtime uwp


【解决方案1】:

要快速解决您的问题,请将该方法设为 public async 并将其传递给 RunAsync 调用。

private async void InstallButton_Click(object sender, RoutedEventArgs e)
{
    await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
    {
        bool installed = await FileManager.InstallAsync(StorageLocation.Local);
    });
}

另外,FileManager 会修改 UI 吗?如果没有,您可以直接等待它而无需调度程序。

private async void InstallButton_Click(object sender, RoutedEventArgs e)
{
    bool installed = await FileManager.InstallAsync(StorageLocation.Local);
}

【讨论】:

  • 我认为可以等待 InstallAsync() 方法,无论它是否修改 UI(它不应该,但它也不应该重要)。为什么您上面的建议建议使用RunAsync()?当方法位于await 语句时,您是否误以为 UI 线程被阻塞?
  • 感谢您的快速回复。我不必更新 UI。问题在于 FileManager 在 WinRT 项目中。它不能返回任务。这就是为什么我创建了安装包装方法来尝试解决这个问题。我想这行不通。也许我可以将它们更改为异常消息中建议的 Windows 运行时类型之一。
  • 当您指出的问题与我提出的问题完全不同时,您已将其标记为重复。
猜你喜欢
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
  • 2018-05-23
  • 2022-07-26
  • 2016-09-05
  • 2018-02-26
  • 2019-04-30
  • 1970-01-01
相关资源
最近更新 更多