【发布时间】:2015-10-22 18:20:52
【问题描述】:
首先,我已经看过this question,并且我(有点)理解为什么我会遇到这个异常,我想知道修复它的最佳方法是什么。我的代码看起来有点像这样(这是一个 WinRT 应用程序):
//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
});
}
}
显然,拥有LoadData 方法async void 并不是最好的解决方案。但是,如您所见,我必须在其中执行一些异步函数调用(从文件中读取数据)。现在我能想到两种可能的解决方案:
- 将
LoadData更改为public async Task LoadData(),并将应用程序构造函数中的调用更改为_model.LoadData().GetAwaiter().GetResult();,以便同步运行; - 将
LoadData更改为public void LoadData(),并将其中的所有await调用更改为使用awaiter,例如StorageFile file = folder.GetFileAsync(@"Assets\Data.json").GetAwaiter().GetResult()。
其中哪一个是更好的解决方案,或者,更好的是,有没有其他合适的方法在应用程序启动时运行异步代码?另外,为什么调度程序行会出现“A method was called at an unexpected time”错误?
【问题讨论】:
-
为什么需要从构造函数初始化模型?有一种更合适的方法来做到这一点。调用
async Task LoadData()方法,例如 App.xaml.cs 的protected async override void OnLaunched(LaunchActivatedEventArgs e)方法,等待:await LoadData()。
标签: c# asynchronous windows-runtime