我想在UWP中创建一些简单的练习代码,打开一个文本文件,然后立即用简单的文本附加该代码。
public MainPage()
{
this.InitializeComponent();
OpenFile();
SaveFile();
}
public async void OpenFile()
{
FileOpenPicker picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.Desktop;
picker.FileTypeFilter.Add(".txt");
DataFile = await picker.PickSingleFileAsync();
if (DataFile == null) { return; }
}
public async void SaveFile()
{
await FileIO.AppendTextAsync(DataFile, "" + DateTime.Now + "\n");
}
private StorageFile DataFile { get; set; }
正如预期的那样,此代码在SaveFile()方法中返回错误,因为SaveFile()在OpenFile()之后立即运行,并且因为OpenFile()尚未完成检索要使用的SaveFile()的目标文件的操作。问题是,当我尝试在OpenFile中修改以下代码时,我收到一个AggregateException错误:
DataFile = picker.PickSingleFileAsync();
Task task = Task.Run( async() => DataFile = await picker.PickSingleFileAsync() );
task.Wait();
我想知道如何在SaveFile()运行之前完成检索目标文件之前阻止OpenFile()。
答案 0 :(得分:2)
类的构造函数应该很快,绝对不应该有任何异步方法。在您的情况下,您已经将这些方法解雇为 fire-forget ,存在竞争条件,您尚未选择文件并尝试保存到该文件。这没有什么好处。
相反,如果您希望用户在创建MainPage后执行此类操作,则可以使用Loaded事件:
public MainPage()
{
this.InitializeComponent();
this.Loaded += LoadedHandler;
}
private async void LoadedHandler(object sender, RoutedEventArgs e)
{
// assume that we want to do this only once
this.Loaded -= LoadedHandler;
await OpenFile();
await SaveFile();
}
public async Task OpenFile()
{
FileOpenPicker picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.Desktop;
picker.FileTypeFilter.Add(".txt");
DataFile = await picker.PickSingleFileAsync();
if (DataFile == null) { return; }
}
public async Task SaveFile()
{
await FileIO.AppendTextAsync(DataFile, "" + DateTime.Now + "\n");
}
private StorageFile DataFile { get; set; }
另请注意,我已将您的方法更改为任务 - 您应该avoid async void。