Perform synchronous operation on Ui thread

后端 未结 2 1664
春和景丽
春和景丽 2020-12-11 22:48

I am trying develop a Windows App and run into issues. I have a MainPage.xaml and 2 others StartScreen.xaml and Player.xaml. I am switching content of the MainPage if certai

相关标签:
2条回答
  • 2020-12-11 22:52

    [Update July 22 2018 with example]

    The error message tells you everything you need to know:

    Consider wrapping this method in Task.Run

    You should wrap the code in a call to Task.Run. This will ensure it runs on a background thread.

    Here is a simple example:

    var picker = new FolderPicker();
    picker.SuggestedStartLocation = PickerLocationId.MusicLibrary;
    picker.FileTypeFilter.Add(".mp3");
    var folder = await picker.PickSingleFolderAsync();
    var result = await Task.Run(() => Directory.Exists(Path.Combine(folder.Path, "foobar")));
    if (result)
    {
      Debug.WriteLine("Yes");
    }
    else
    {
      Debug.WriteLine("No");
    }
    

    Background information in case anyone cares:

    I assume, based on your sample code, that you are reading the Music Library. In this case, the .NET file APIs go through the WinRT APIs under the covers since it is a brokered location. Since the underlying WinRT APIs are async, .NET has to do work to give you the illusion of synchronous behaviour, and they don't want to do that on the UI thread.

    If you were only dealing with your own local data folders, the .NET APIs would use the underlying Win32 APIs (which are synchronous already) and so would work without any background thread requirements.

    Note that on my machine, this appears to work even on the UI thread, so it might depend on the version of Windows that you are targeting.

    0 讨论(0)
  • 2020-12-11 23:10

    As the exception says, you are not allowed to call Directory.Exists synchronously in the UI thread. Putting the whole code block in a Dispatcher action still calls it in the UI thread.

    In a UWP app you would usually use the StorageFolder.TryGetItemAsync method to check if a file or folder exists:

    private async void GoToPlayer_Click(object sender, RoutedEventArgs e)
    {
        var folder = await StorageFolder.GetFolderFromPathAsync(main.workingDir);
    
        if ((folder = await folder.TryGetItemAsync(IDText.Text) as StorageFolder) != null &&
            (folder = await folder.TryGetItemAsync("Tracks") as StorageFolder) != null)
        {
            ...
        }
    }
    

    Note that you may still get an UnauthorizedAccessException when the application is not allowed to access main.workingDir.

    0 讨论(0)
提交回复
热议问题