Приложение С# должно быть асинхронным, но пользовательский интерфейс все еще зависает

Я создал небольшое приложение С#, которое должно извлекать все значения из файла XML асинхронно. Проблема в том, что это не асинхронно, и я не вижу, где я ошибаюсь. Когда кнопка нажата, пользовательский интерфейс зависает, приложение не может перемещаться и т.д., Показывая все признаки его работы синхронно.

Кто-нибудь может понять, почему это происходит?

private async void parseAndExportBtn_Click(object sender, EventArgs e)
{
 progressBar1.MarqueeAnimationSpeed = 100;
 parseAndExportBtn.Enabled = false;
 selectDirectoryBtn.Enabled = false;
 status.Text = "Started searching files...";
 await SearchFiles(selectTxcDirectory.SelectedPath);
 status.Text = "Finished searching files";
}
private static async Task SearchFiles(string path)
{
 XmlDocument xmlDoc = new XmlDocument();
 xmlDoc.Load(path + "/cen_18-2_-1-y11.xml");
 using (XmlReader r = XmlReader.Create(new StringReader(xmlDoc.InnerXml), new XmlReaderSettings() { Async = true }))
 {
 while (await r.ReadAsync())
 {
 switch (r.NodeType)
 {
 case XmlNodeType.Text:
 Console.WriteLine(await r.GetValueAsync());
 break;
 }
 }
 }
}
2 ответа

Вызовите SearchFiles(string path) в Task. Как показано ниже.

private void parseAndExportBtn_Click(object sender, EventArgs e)
{
 progressBar1.MarqueeAnimationSpeed = 100;
 parseAndExportBtn.Enabled = false;
 selectDirectoryBtn.Enabled = false;
 status.Text = "Started searching files...";
 Task t = Task.Run(() => SearchFiles(selectTxcDirectory.SelectedPath));
 status.Text = "Finished searching files";
}

Я предлагаю вам прочитать эту статью в async и await ключевых словах.


Я предполагаю, что проблема связана с XmlDocument.Load, которая загружается синхронно.

Попробуйте использовать XmlReader, созданный из асинхронного потока файлов.

using (var file = new FileStream(path + "/cen_18-2_-1-y11.xml", FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true))
using (XmlReader r = XmlReader.Create(file, new XmlReaderSettings() { Async = true }))
{
 while (await r.ReadAsync())
 {
 switch (r.NodeType)
 {
 case XmlNodeType.Text:
 Console.WriteLine(await r.GetValueAsync());
 break;
 }
 }
}

licensed under cc by-sa 3.0 with attribution.