【问题标题】:BackgroundWorker DoWork delegate fails when using XmlReader使用 XmlReader 时 BackgroundWorker DoWork 委托失败
【发布时间】:2011-07-25 15:43:18
【问题描述】:

我正在尝试使用 BackgroundWorker 读取 XML 流:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
            NetworkStream serverStream = clientSocket.GetStream();
            XmlReader r = XmlReader.Create(serverStream);

            while (r.Read())
            {
  output something using backgroundWorker1.ReportProgress object
            }
    }

我在按钮点击事件中使用backgroundWorker1.RunWorkerAsync(null) 调用它。

程序编译并运行良好,但进程停在XmlReader.Create。没有错误,但它说它无法评估表达式,因为本机框架位于调用堆栈的顶部。所以,它可能正在等待进程完成。

问题是,如果我直接通过鼠标单击而不使用 backgroundWorker 对象来执行此操作,则程序运行得很好。

有什么想法吗?谢谢。

【问题讨论】:

  • 如何传递“clientSocket”?您是否 100% 确定它是相同的并且没有在 bgw 之外使用?
  • 你能贴出调用代码吗(在 RunWorkerAsync(null) 附近)?
  • (在下面的 cmets 之后) - 发布所有与 clientSocket 相关的代码。没有它,这个问题就无法回答。

标签: c# xml backgroundworker xmlreader


【解决方案1】:

The documentation 表示XmlReader.Create 读取前几个字节以确定编码。
我认为问题在于,您的流不返回任何数据。这可能是因为另一个线程已经读取了所有数据。

【讨论】:

  • 但这正是问题所在。如果我不使用 backgroundWorker,它就可以正常工作。例如,如果我将方法包含在鼠标单击事件中,它会按原样运行。我需要做些什么才能使 xmlReader 与 backgroundWorker 一起工作吗?
  • @Henk:您的评论暗示您认为我没有正确阅读他的问题。你错了。再次阅读我的答案:“可能是这种情况,因为另一个线程已经读取了所有数据。”。当他在 UI 线程上使用他的代码时,(很可能)只有一个线程。现在他介绍了BackgroundWorker,他有两个线程。在调用 BackgroundWorker 之后,UI 线程可以继续并读取网络流,这可能会导致他的问题。
  • @Daniel:我调用 xmlReader.Create 的唯一位置是在 backgroundWorker 中。 UI线程是否仍然有可能正在读取流?如果是,我该如何解决?
  • @snaee:请按照 Henk 的要求显示按钮单击处理程序的代码。
  • 这里是:private void startScan_Click(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(null);}
【解决方案2】:

听起来 XML 阅读器的创建在读取流时被阻止了。

  • 可能会出现死锁情况,在后台工作线程执行某些任务之前,服务器流不会发送字节(但似乎不太可能)

  • 正如@Daniel Hilgarth 建议的那样,也许另一个线程之前已经完全读取了流?

这里也可能存在一些同步问题。尝试在代码周围添加锁定语句,例如:-

private readonly object streamLocker = new object();

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    lock(streamLocker)
    {
        NetworkStream serverStream = clientSocket.GetStream();
        XmlReader r = XmlReader.Create(serverStream);

        while (r.Read())
        {
          //  output something using backgroundWorker1.ReportProgress object
        }
    }
}

【讨论】:

  • 我尝试了 lock 语句,但没有奏效。正如其他人(@Henk ...)所建议的那样,backgroundWorker 可能会在 UI 流读取数据后尝试访问流。这可能是个问题,但我不知道 UI 线程在哪里读取数据,因为我调用 XMLReader.Create 的唯一位置是在 backgroundWorker....
猜你喜欢
  • 1970-01-01
  • 2011-09-10
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 2012-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多