如何在UWP for FileOpenPicker中等待异步方法?

时间:2017-10-07 04:42:34

标签: c# .net asynchronous uwp

我想在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()。

1 个答案:

答案 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