首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows RT -同步使用StorageFile

Windows RT -同步使用StorageFile
EN

Stack Overflow用户
提问于 2013-04-29 16:54:04
回答 2查看 2.3K关注 0票数 3

我想写一个Win8应用,在那里我使用了一个带有static成员的Configuration-class,它在启动时加载一次,在运行时可以从任何地方访问。

所以,主要的问题是,默认设置存储在xml文件中,但读取文件内容是异步的(StorageFile),但是我没有找到任何解决方案来等待,直到文件完全加载,因为不可能在所有情况下(主线程、构造函数)都使用await,这在我看来是一个设计问题。如果在访问Configuration数据之前没有完全读取文件,则此应用程序将出现不正确的行为。

下面是一个示例代码:

代码语言:javascript
复制
public class Configuration
{
    // stores the only instance of this class
    private Configuration instance = null;

    // public access to the instance
    public Configuration Current
    {
        get
        {
            if (instance == null)
            {
                instance = new Configuration();
            }

            return instance;
        }
    }

    private Configuration()
    {
        // load data from file synchronously
        // so it is loaded once on first access
    }
}

我不确定,如何解决这个问题,也许我需要改变我的Configuration-class的设计。任何建议/提示都会很好。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-30 12:35:55

这是一个设计决策,不允许任何可能耗时超过50ms的同步调用,即任何文件或网络IO调用,以使应用程序更具响应性。

尽管您不能从构造函数await异步调用,但没有什么可以阻止您在不等待调用完成的情况下触发此类调用:

代码语言:javascript
复制
private Configuration()
{
    Init();
}

private async void Init()
{
    var contents = await FileIO.ReadTextAsync(file);
}

然后,您可以从Init()内部设置Configuration属性。如果实现INotifyPropertyChanged,则可以在加载之前将值绑定到UI,一旦加载,UI就会刷新。

如果您需要在应用程序中的某个时刻检查或等待操作完成,可以更改Init()的签名以返回Task

代码语言:javascript
复制
private Configuration()
{
    InitTask = Init();
}

private async Task Init()
{
    var contents = await FileIO.ReadTextAsync(file);
}

public Task InitTask { get; private set; }

现在可以检查是否完成了:

代码语言:javascript
复制
if (Configuration.Current.IsCompleted)
{
    //
}

或者甚至await它(如果Task已经完成,这将立即完成):

代码语言:javascript
复制
await Configuration.Current.InitTask;

编辑:

如果在加载上述文件之前,向用户显示任何内容都没有意义,您可以修改您的入口页面,使其具有替代的“视图”:

屏幕实际视图(您希望用户在应用程序显示ready)

  • splash

  • 视图(例如,显示进度指示器)时看到)

您可以基于IsCompleted属性使正确的视图可见,您应该在实现了INotifyPropertyChanged的视图模型上公开该属性。

然后,您可以按如下方式设计页面:

代码语言:javascript
复制
<Page xmlns:common="using:MyApp.Common">
    <Page.Resources>
        <common:BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
    </Page.Resources>
    <Grid>
        <Grid Visibility="{Binding Configuration.IsCompleted, Converter={StaticResource BoolToVisibilityConverter}">
            <!-- put your actual view here -->
        </Grid>
        <Grid Visibility="{Binding Configuration.IsNotCompleted, Converter={StaticResource BoolToVisibilityConverter}">
            <!-- put your splash screen view here -->
        </Grid>
    </Grid>
</Page>
票数 4
EN

Stack Overflow用户

发布于 2013-04-29 17:10:45

你不需要另一个类来存储设置--为每个Windows8应用程序提供了AplicationData.Current.LocalSettings字典,该字典在应用程序每次启动时自动加载,并且您可以在没有await关键字的情况下读取它-例如:

代码语言:javascript
复制
var settings = ApplicationData.Current.LocalSettings;
settings.Values["MyIndex"] = 2;

object value = settings.Values["MyIndex"];
if (value != null)
{
     int myIndex = (int)value;
     //...
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16274684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档