在我的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中,应用程序将阻塞。看起来任务从未完成,但文件已经创建。
它里面的原因是什么?
发布于 2020-10-24 07:37:45
对于异步和等待模式,惯用的方法是对任务执行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);
}https://stackoverflow.com/questions/64508477
复制相似问题