Windows RT -同步使用的存储文件

本文关键字:存储文件 同步 RT Windows | 更新日期: 2023-09-27 18:11:31

我想写一个Win8应用程序,在那里我使用Configuration -类与static成员,这是加载一次启动,可以在运行时从任何地方访问。

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

下面是一个示例代码:
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类的设计。如有任何建议或提示,我将不胜感激。

Windows RT -同步使用的存储文件

这是一个设计决定,不允许任何可能超过50毫秒的同步调用,即任何文件或网络IO调用,以使应用程序响应更快。

虽然你不能从构造函数await异步调用,没有什么可以阻止你触发这样的调用而不等待它们完成:

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

你可以在Init()内部设置Configuration属性。如果你实现了INotifyPropertyChanged,你可以在这些值被加载之前绑定到UI,并且UI将在它们加载后刷新。

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

private Configuration()
{
    InitTask = Init();
}
private async Task Init()
{
    var contents = await FileIO.ReadTextAsync(file);
}
public Task InitTask { get; private set; }

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

if (Configuration.Current.IsCompleted)
{
    //
}

await it(如果Task已经完成,这将立即完成):

await Configuration.Current.InitTask;
编辑:

如果在加载文件之前没有必要向用户显示任何内容,则可以修改条目页,使其具有可选的"views":

  • 实际视图(你想让用户看到应用程序准备好了)
  • 闪屏视图(例如显示进度指示器)

你可以使正确的一个可见的基于IsCompleted属性,你应该暴露在你的视图模型与INotifyPropertyChanged实现。

你可以这样设计你的页面:

<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>

你不需要另一个类来存储设置-有AplicationData.Current.LocalSettings字典提供给每个Windows 8应用程序,每次应用程序启动时自动加载,你阅读它没有await关键字-例如:

var settings = ApplicationData.Current.LocalSettings;
settings.Values["MyIndex"] = 2;
object value = settings.Values["MyIndex"];
if (value != null)
{
     int myIndex = (int)value;
     //...
}