在Ui线程上执行同步操作 [英] Perform synchronous operation on Ui thread

查看:132
本文介绍了在Ui线程上执行同步操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发Windows App并遇到问题. 我有一个MainPage.xaml和另外2个StartScreen.xaml和Player.xaml. 如果满足某些条件,我将切换MainPage的内容. 因此,我在StartScreen中有一个事件,它检查目录是否存在,但是每次出现错误时都会抛出该错误.

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 certain conditions are true. So I have an event in StartScreen it checks if a directory exist or not but it throws me every time an error.

private void GoToPlayer_Click(object sender, RoutedEventArgs e)
    {

        if (Directory.Exists(this.main.workingDir + "/" + IDText.Text + "/Tracks")) // Error occurs here
        {
            this.main.Content = this.main.player; //here i switch between different ui forms
        }
        else
        {
            MessageBox.Text = "CD not found";
            IDText.Text = "";
        }

    }

当它击到else分支时,一切都很好,但是当dir可用时,我收到以下错误消息:

When it hit the else branch everything is fine but when the dir is available I get the following error message:

An exception of type 'System.InvalidOperationException' occurred in System.IO.FileSystem.dll but was not handled in user code

其他信息:不应在UI线程上执行同步操作.考虑将此方法包装在Task.Run中.

Additional information: Synchronous operations should not be performed on the UI thread. Consider wrapping this method in Task.Run.

即使我在if分支中注释了代码,错误仍然会出现.

Even if I commenting the code in the if branch out the error still comes.

我尝试过:

private async void GoToPlayer_Click(object sender, RoutedEventArgs e)
    {
        await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
            if (Directory.Exists(this.main.workingDir + "/" + IDText.Text + "/Tracks")) // Error occurs here
            {
                this.main.Content = this.main.player; //here i switch between different ui forms
            }
            else
            {
                MessageBox.Text = "CD not found";
                IDText.Text = "";
            }
        });
    }

仍然是相同的错误,据我所知,应该异步运行并等待代码完成,但事实并非如此.我也尝试了一堆其他的东西,但仍然得到错误. 我不知道如何解决该问题,有人可以解释一下为什么会发生这种情况以及如何解决该问题.

Still the same error, as I understood this should be run asynchronous and wait until the code complete, but it doesn't seems so. I also tried bunch other stuff but still get the errors. I don't know how to fix that, could someone please explain why this is happening and how to fix that.

推荐答案

[以示例更新2018年7月22日]

[Update July 22 2018 with example]

错误消息告诉您所有您需要了解的内容:

The error message tells you everything you need to know:

考虑将此方法包装在Task.Run中

Consider wrapping this method in Task.Run

您应该将代码包装在对 Task.Run .这样可以确保它在后台线程上运行.

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

这是一个简单的例子:

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");
}

万一有人在意的背景信息:

根据您的示例代码,我假设您正在阅读音乐库.在这种情况下,.NET文件API会通过WinRT API进行隐藏,因为它是代理位置.由于基本的WinRT API是异步的,因此.NET必须做一些工作,以使您产生同步行为的错觉,而他们不想在UI线程上做到这一点.

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.

如果仅处理自己的本地数据文件夹,则.NET API将使用基础的Win32 API(它们已经是同步的),因此可以在没有任何后台线程要求的情况下工作.

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.

请注意,在我的计算机上,即使在UI线程上也可以使用,因此可能取决于您所针对的Windows版本.

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.

这篇关于在Ui线程上执行同步操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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