我想编写一个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
- 类的设计。任何建议/提示都会很好。
答案 0 :(得分:4)
这是一项设计决定,不允许任何可能需要超过50毫秒的同步调用,即任何文件或网络IO调用,以使应用程序更具响应性。
虽然您无法await
来自构造函数的异步调用,但没有任何东西阻止您在不等待它们完成的情况下触发此类调用:
private Configuration()
{
Init();
}
private async void Init()
{
var contents = await FileIO.ReadTextAsync(file);
}
然后,您可以在Configuration
内设置Init()
属性。如果您实现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
它(如果Task
已经完成,这将立即完成):
await Configuration.Current.InitTask;
编辑:
如果在加载所述文件之前向用户显示任何内容没有意义,您可以修改您的输入页面以使用其他“视图”:
您可以根据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>
答案 1 :(得分:1)
您不需要另一个类来存储设置 - 为每个Windows 8应用程序提供AplicationData.Current.LocalSettings
字典,每次启动应用程序时都会自动加载该字典,而您在没有await
关键字的情况下阅读它例如:
var settings = ApplicationData.Current.LocalSettings;
settings.Values["MyIndex"] = 2;
object value = settings.Values["MyIndex"];
if (value != null)
{
int myIndex = (int)value;
//...
}