在我的WPF应用程序中,我使用按钮单击来创建一个XML文件。如果异步任务成功完成,则从中获取反馈并显示消息框。
Window.cs
public partial class BindXml : Window
{
public BindXml()
{
InitializeComponent();
}
private void Create_File_OnClick(object sender, RoutedEventArgs e)
{
XmlCreator xmlCreator = new XmlCreator();
Task task = xmlCreator.CreateXmlAysnc();
MessageBox.Show(task.IsCompletedSuccessfully
? "XML Created Successfully."
: "Wrong");
}
XmlCreator.cs
public async Task CreateXmlAysnc()
{
string filePath =
"E:\OneDrive\Programming\C#\03_Csharp\02_WPF\06_DataBinding\03_Binding\09_BindXml\data.xml";
// Create a xml tree.
XDocument xmlDocument = new XDocument(
new XElement("StudentList",
new XElement("Student",
new XAttribute("Id", "1"),
new XElement("Name", "Tim")),
new XElement("Student",
new XAttribute("Id", "2"),
new XElement("Name", "Gary")),
new XElement("Student",
new XAttribute("Id", "3"),
new XElement("Name", "Tom")))
);
try
{
await using FileStream fileStream = File.Open(filePath, FileMode.Create);
await xmlDocument.SaveAsync(fileStream, SaveOptions.None, CancellationToken.None);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
throw;
}
}
点击按钮后,文件创建成功。然而,消息框显示;错了";。任务未成功完成。然后我使用了下面的代码。消息框将显示为true。
Task task = xmlDocument.SaveAsync(fileStream, SaveOptions.None, CancellationToken.None);
await Task.WhenAll(task);
// Messagebox would show true
MessageBox.Show(task.IsCompletedSuccessfully.ToString());
如果我将Task.Wait()
添加到Window.cs中,应用程序就会阻塞。任务似乎从未完成,但文件已创建。
里面的原因是什么?
对于异步和等待模式,惯用方法是await
(任务(和catch
(异常。
因为您来自事件处理程序,所以使用async void
来利用异步和等待模式是可以接受的,而不必担心原始任务或更糟的是,尝试使用Wait
或任何其他阻塞方法。
此外,当在async
方法中产生异常时,它被放置在任务上,并将被抛出到await
,从而使您能够流畅地处理它,同时也允许延续在原始上下文中运行。
示例
private async void Create_File_OnClick(object sender, RoutedEventArgs e)
{
try
{
XmlCreator xmlCreator = new XmlCreator();
await xmlCreator.CreateXmlAysnc();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
public async Task CreateXmlAysnc()
{
...
await using FileStream fileStream = File.Open(filePath, FileMode.Create);
await xmlDocument.SaveAsync(fileStream, SaveOptions.None, CancellationToken.None);
}