I have created a Windows 8 Metro App based on the Split Page sample app. However, in the sample app the data is loaded synchronously in the constructor. I'm accessing a text file and therefore need to load the data asynchronously. The constructor looks like this:
public MyDataSource()
{
DataLoaded = false;
LoadData();
}
LoadData() is an asynchronous method that populates the data model. This works fine, and displays the data as is loads it (which is the behavior that I want). The problem occurs when I try testing the suspend and terminate. The problem being that the recovery has the potential to attempt to access the data model before it is populated:
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;
}
I can fix this by changing the constructor to call LoadData().Wait, but this means that the app locks the UI thread. What I believe I need is a method of getting the recovery code in GetGroup to wait until the data has loaded without locking the UI thread. Is this possible or advisable, and if so, how?
EDIT:
One or two people have suggested caching the task for LoadData(). This is an excellent idea, but the code inside GetGroup is called by the Page State Management section and therefore cannot be async. To get around this, I tried the following:
if (!DataLoaded)
{
//dataLoading = await MyDataSource.LoadData();
dataLoading.RunSynchronously();
}
But this gives me an error:
RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
and
dataLoading.Wait()
just locks the UI.