2017-10-07 19 views
0

我想在UWP中创建一些打开文本文件的简单练习代码,然后立即在代码中添加简单的文本。如何在UWP中为FileOpenPicker等待异步方法?

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

这可以通过在这个问题中的答案来解决:https://stackoverflow.com/questions/32084943/async-lock-not-allowed – Laith

+0

异步撰写不佳,这是乌龟一路下来,这里的核心问题是最后的乌龟,构造函数不能是异步的。你只需要做相反的事情,*首先*要求一个文件名,*然后*创建类对象。它的名字是MainPage并不好,在显示任何用户界面之前不要立即在程序启动时要求用户输入。对话框需要一个窗口来保持。否则,程序通常会有一个File> Open命令。 –

回答

2

一个类的构造函数应该很快,绝对不应该有任何异步方法。在你的情况下,你已经发射这些方法为火灾忘记,有一个竞争条件,你没有选择一个文件,并尝试保存到它。这没什么好处。

相反,如果你想一旦你创建一个的MainPage用户做soemthing,您可以例如使用加载事件这样的:

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

+1

将它们转换为'Task'本身并没有什么帮助......你没有在try/catch中调用,调用者(事件处理程序)是“void”,所以异常仍然会泄漏到'未观察到的例外情况。 –

+0

@ PeterTorr-MSFT在这种情况下,你是对的。编辑后提供的链接应该给读者一些亮点。我已经添加了这个提及可能的问题。 – Romasz