WinRT:使用GetFileFromApplicationUriAsync()加载静态数据

时间:2012-09-02 10:11:59

标签: c# asynchronous windows-8 windows-runtime winrt-xaml

我的Windows 8应用程序中有一些数据应该随附,并且只是一些静态数据。实际上:它是一个简单的xml文件,应该反序列化。

数据保存在Assets \ data.xml中(资产是空白应用程序模板中的默认文件夹)。

我正在使用这段代码来访问它:

private static async Task<MyObject> Load()
{
    if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
    {
        return new SampleData();
    }

    var uri = new Uri("ms-appx:///Assets/data.xml");
    Debug.WriteLine("Getting file from Application");
    var file = await StorageFile.GetFileFromApplicationUriAsync(uri);
    Debug.WriteLine("Opening file for reading async");
    var stream = await file.OpenStreamForReadAsync();

    var serializer = new XmlSerializer(typeof(MyObject));

    Debug.WriteLine("Begin deserialization");
    var result = (MyObject)serializer.Deserialize(stream.AsInputStream().AsStreamForRead());

    return result;
}

通话方式:

public static MyObject GetMyObject()
{
    if (_myObject == null)
    {
        _myObject = Load().Result;
    }

    return _myObject;
}

关于这个的“有趣”部分是:

如果我在var uri = new Uri(...);设置断点并使用F11逐步执行代码,则一切都按预期工作。我获得了所有的调试行,我的应用程序显示了所需的静态数据。

如果我没有设置断点并且没有跨过这段代码,我只得到Getting a file from Application的调试输出,而不会发生任何其他事情。似乎GetFileFromApplicationUriAsync()永远不会回来。我等了五分多钟,但仍然没有发生任何事情。

有人有任何想法吗?

1 个答案:

答案 0 :(得分:11)

感谢您发布代码。请尝试按以下方式更改您的方法Load

//your code
var file = await StorageFile.GetFileFromApplicationUriAsync(uri).AsTask().ConfigureAwait(false);
//your code
var stream = await file.OpenStreamForReadAsync().ConfigureAwait(false);
//your code

这里的主要区别是 AsTask()。ConfigureAwait(false)

修改

很高兴听到它正在发挥作用。解释非常简单:当您在GUI线程上使用task.Resulttask.Wait()并结合await关键字时,您将导致死锁。发生这种情况是因为awaiting代码在调用它的同一个上下文后恢复(在你的情况下是GUI线程)。并且因为GUI线程当前正在等待任务完成(通过ResultWait())死锁,并且await关键字之后的代码将永远不会被调用。 ConfigureAwait(false)指定可以忽略当前上下文,从而允许您的代码成功完成。有关详细信息,请访问:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html