2017-04-24 105 views
0

我想將xml配置文件從安裝目錄移動到本地目錄。當它到達StorageFolder.GetFilesAsync()時,它會凍結應用程序並永不恢復。StorageFolder.GetFilesAsync()凍結UWP和WinRT應用程序

我打電話的代碼是在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); 
} 
+1

嘗試調用'await FileManager.InstallAsync(StorageLocation.Local);'在您的按鈕中單擊而不是等待它。不要讓異步代碼同步運行 - 你可能會在[Stephen Cleary的博客](https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html)上閱讀有關死鎖的內容。另一件事 - IsInstalled(位置)是什麼? - 它是另一種同步等待異步代碼的方法(如'.Result')? – Romasz

+0

另一個問題 - 爲什麼你運行這個* Distpatcher *? – Romasz

回答

0

要快速解決您的問題,使該方法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); 
} 
+0

我認爲可以等待'InstallAsync()'方法,無論它是否修改UI(它不應該,但它也應該不重要)。爲什麼上面的提議建議使用'RunAsync()'?你是否誤解了當一個方法處於'await'語句時UI線程被阻塞? –

+0

感謝您的快速回復。我不必更新UI。這個問題是FileManager在WinRT項目中。它不能返回任務。這就是爲什麼我創建了安裝包裝器方法來嘗試解決這個問題。我想這沒有用。也許我可以將它們更改爲異常消息中建議的Windows運行時類型之一。 – Haydn

+0

當您指出的問題與我問的問題完全無關時,您已將其標記爲重複項。 – Haydn