XDocument.Load()导致System.InvalidOperationException XAML C#

时间:2016-01-01 17:54:09

标签: c# xaml exception win-universal-app

要从用户指定的文件中解析某些XML,我有以下C#代码:

private async void AskUserForFile()
{
    var FilePicker = new Windows.Storage.Pickers.FileOpenPicker();
    FilePicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
    FilePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.ComputerFolder;
    FilePicker.FileTypeFilter.Add(".pcs");
    FilePicker.FileTypeFilter.Add(".pcp");

    XMLFile = await FilePicker.PickSingleFileAsync();
    ParseXML();
}

private void ParseXML()
{
    XDocument Files = XDocument.Load(XMLFile.Path);
}

返回以下错误:

  

类型' System.InvalidOperationException'的例外情况发生在System.IO.FileSystem.dll中但未在用户代码中处理附加信息:不应在UI线程上执行同步操作。考虑在Task.Run中包装此方法。

有人可以帮我弄清楚为什么会发生这种情况以及如何解决这个问题?提前谢谢。

注意:我正在为通用Windows编程。

2 个答案:

答案 0 :(得分:1)

下面的代码之类的东西可以让你超越错误,但它有点违背了异步方法的目的。

我不能给你一个关于你的项目的具体例子,但是'askuserforfile'操作可能会触发一个构建你的xml的事件,以支持现代windows app开发的整个'非阻塞线程'概念。或者在异步操作完成后要求用户创建文件的模型上挂钩'onpropertynofitychange'。

注意:在下面的代码段中,删除我插入的Task.Wait(),以便在我的结束时进行调试...除非你需要在下一个操作开始之前构建xml。

public class Ans34558541
{
    public StorageFile XMLFile { get; private set; }
    public XDocument Files { get; private set; }

    private async void AskUserForFile()
    {
        var FilePicker = new Windows.Storage.Pickers.FileOpenPicker();
        FilePicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
        FilePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.ComputerFolder;
        FilePicker.FileTypeFilter.Add(".pcs");
        FilePicker.FileTypeFilter.Add(".pcp");

        XMLFile = await FilePicker.PickSingleFileAsync();
        Action Act = new Action(ParseXML);
        Task Tsk = new Task(Act);
        Tsk.Start();
        Tsk.Wait();
    }

    private async void ParseXML()
    {
        String xml = await FileIO.ReadTextAsync(XMLFile);
        File = XDocument.Parse(xml);
    }
}

答案 1 :(得分:0)

它在错误中给你答案。 “不应在UI线程上执行同步操作。请考虑在Task.Run中包装此方法。”

您不应该在UI线程上执行文件的同步加载。尝试将您的调用包装在Task.Run中。您可以使用Lambda表示法来轻松完成。

https://msdn.microsoft.com/en-us/library/hh195051(v=vs.110).aspx