First of all, I've already seen this question, and I (kind of) understand why I'm getting this exception, I would like to know what is the best way to fix it. My code looks somewhat like this (this is a WinRT application):
//Here is my App constructor:
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
//Initializing the model
_model = new Model();
_model.LoadData();
}
//the LoadData method looks like this:
public async void LoadData()
{
StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await folder.GetFileAsync(@"Assets\Data.json");
string data = await FileIO.ReadTextAsync(file);
var dataList = JsonConvert.DeserializeObject<List<MyDataClass>>(data);
// From time to time (pretty rarely, honestly) this line causes the
// "A method was called at an unexpected time" thing:
var dispatcher = CoreApplication.MainView.CoreWindow.Dispatcher;
foreach (var item in dataList)
{
//do some stuff
//<...>
await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
() => {
//do some stuff in the UI thread
});
}
}
Obviously, having the LoadData
method async void
is not the best solution. However, as you can see, I have to do some async function calls (to read data from a file) inside of it. Right now I can think of two possible solutions:
- Change
LoadData
topublic async Task LoadData()
and change it's call in the application constructor to_model.LoadData().GetAwaiter().GetResult();
in order to run it synchronously; - Change
LoadData
topublic void LoadData()
, and change all theawait
calls inside of it to use the awaiter, e.g.StorageFile file = folder.GetFileAsync(@"Assets\Data.json").GetAwaiter().GetResult()
.
Which of these is a better solution, or, better yet, is there any other proper way to run async code on the application startup? Also, why is the "A method was called at an unexpected time" error happening on the dispatcher line?