我已经基于 Split Page 示例应用程序创建了一个 Windows 8 Metro 应用程序。但是,在示例应用程序中,数据是在构造函数中同步加载的。我正在访问一个文本文件,因此需要异步加载数据。构造函数如下所示:
public MyDataSource()
{
DataLoaded = false;
LoadData();
}
LoadData()
是一种填充数据模型的异步方法。这工作正常,并在加载数据时显示数据(这是我想要的行为)。当我尝试测试挂起和终止时出现问题。问题在于恢复有可能在填充之前尝试访问数据模型:
public static MyDataGroup GetGroup(string uniqueId)
{
// If the data hasn't been loaded yet then what?
if (_myDataSource == null)
{
// Where app has been suspended and terminated there is no data available yet
}
// Simple linear search is acceptable for small data sets
var matches = _myDataSource.AllGroups.Where((group) => group.UniqueId.Equals(uniqueId));
if (matches.Count() == 1) return matches.First();
return null;
}
我可以通过将构造函数更改为调用 LoadData().Wait
来解决此问题,但这意味着应用程序会锁定 UI 线程。我认为我需要的是一种在 GetGroup
中获取恢复代码的方法,以便在不锁定 UI 线程的情况下等待数据加载。这可能或可取吗?如果可以,怎么做?
编辑:
一两个人建议缓存 LoadData()
的任务。这是个好主意,但是 GetGroup
中的代码是由页面状态管理部分调用的,因此不能异步。为了解决这个问题,我尝试了以下方法:
if (!DataLoaded)
{
//dataLoading = await MyDataSource.LoadData();
dataLoading.RunSynchronously();
}
但这给了我一个错误:
RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
和
dataLoading.Wait()
只是锁定 UI。
最佳答案
我认为这听起来是最好的选择,如果您将构造函数设为 async
。但是自 that's not possible 以来,您可以做的是为 MyDataSource
创建一个 async
工厂方法:
private MyDataSource()
{
DataLoaded = false;
}
public static async Task<MyDataSource> Create()
{
var source = new MyDataSource();
await source.LoadData();
return source;
}
然后使用await
初始化_myDataSource
:
_myDataSource = await MyDataSource.Create();
如果由于某种原因,您不能这样做,您可以存储工厂方法返回的 Task
并在 GetGroup()
中等待它:
_myDataSourceTask = MyDataSource.Create();
…
public static async Task<MyDataGroup> GetGroup(string uniqueId)
{
var myDataSource = await _myDataSourceTask;
// Simple linear search is acceptable for small data sets
var matches = myDataSource.AllGroups.Where(group => group.UniqueId == uniqueId);
if (matches.Count() == 1) return matches.First();
return null;
}
关于c# - Windows Metro 异步加载数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11547251/