【问题标题】:C# app supposed to be asynchronous but UI still freezesC# 应用程序应该是异步的,但 UI 仍然冻结
【发布时间】:2013-09-25 12:30:22
【问题描述】:

我创建了一个小型 C# 应用程序,它应该异步地从 XML 文件中提取所有值。问题是..它不是异步的,我看不出哪里出错了。单击按钮时,UI 冻结,应用程序无法移动等,显示它同步运行的所有迹象。

谁能明白为什么会这样?

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;
            }
        }
    }
}

【问题讨论】:

  • SearchFiles 需要在 Task 内完成。目前它不是异步的。
  • 可能是xmlDoc.Load 使应用程序冻结?这会冻结多长时间?
  • 是的,正如@sam 在Task<T> 中指出的SearchFiles 并继续使用 Ui 线程将是适当的
  • 我在这里看不到任何异步。使用await 意味着“阻止直到我得到结果”。 await 在整个代码中乱扔垃圾。因此为什么会阻塞。
  • @SimonWhitehead: await 实际上 必须 用于“一直向上”调用堆栈以使其行为正常 - 它有点“增长”通过代码库.如果您遇到阻塞的情况,那么您应该发布一个问题,因为它当然不应该这样做。 :)

标签: c# xml asynchronous xmlreader


【解决方案1】:

Task 中致电SearchFiles(string path)。如下。

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";
}

我建议你在 asyncawait 关键字上使用 read this article

【讨论】:

  • -1。没有必要将 I/O 绑定操作包装在线程池任务中,并且无论如何您都不应该使用 StartNew(就像我 describe on my blog 一样)。
  • 这解决了问题并使应用程序异步运行。 :)
【解决方案2】:

我猜这个问题是由于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;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多