【问题标题】:Load on Threads is Locking Up GUI线程负载正在锁定 GUI
【发布时间】:2015-11-17 06:42:21
【问题描述】:

我的应用程序是一个通信服务器,它从 Web 服务器接收 TCP 消息,然后将消息重新广播到多个 iPad。它是 C# 中的 Windows 窗体应用程序。 Program.cs 创建主窗体的一个实例,然后该窗体创建四个线程来执行通信工作。有一个线程监听来自 Web 服务器的消息,一个线程将传入消息处理为需要传输的数据,还有一个线程处理发送出站消息。第四个线程进行数据库清理,99% 的时间都在休眠。

我看到的问题是 GUI 因系统负载而锁定。传入消息可能代表 50 或 100 条传出消息。在测试时,我将他们的系统限制为一次只能发送 5 条消息,因此需要更长的传输时间。发送过程使用异步回调,但即使不是,我也无法理解为什么胎面上的负载可能会停止 GUI 线程。

我删除了大部分从线程到 GUI 的跨线程通信以进行状态更新。与 GUI 通信的模式是:

public void StatusOutput(string myString)
{
    if (this.lbStatus.InvokeRequired)
    {
        this.lbStatus.BeginInvoke(new DebugOutputInvoker(StatusOutput), myString);
    }
    else
    {
        lbStatus.Items.Add(myString);
        while (lbStatus.Items.Count >= 501)
        {
            lbStatus.Items.RemoveAt(0);
        }
        lbStatus.SelectedItem = lbStatus.Items.Count - 1;
}    // StatusUpdate() ...

谁能给我任何关于如何追求这个的建议?我虽然线程与 GUI 完全隔离并且无法加载它。

谢谢!

【问题讨论】:

  • 获得无响应 UI 的常见方法是在 UI 线程上执行大量工作,从而占用 UI 线程,使其无法为其他 UI 事件提供服务。对可用的有限信息进行疯狂的推测,是否有可能 - 在负载下 - 你的 lbStatus.Items.Count 变得如此之大以至于 while 循环永远不会退出?例如,如果 Count > 501 和其他线程添加到 lbStatus.Items 的速度比 UI 线程在 RemoveAt 上循环的速度要快?
  • 有趣的想法!也许我应该为状态显示设置一个队列,然后让 UI 线程从队列中的消息更新它自己的显示,然后只有一个线程正在写入 GUI 对象。
  • 我之前的评论有点垃圾。再考虑一下,您似乎正在使用BeginInvoke 在UI 线程上运行StatusOutput,所以(也许?)唯一添加到lbStatus.Items 的线程是UI 线程。在某种程度上我猜是因为我们不知道thislbStatus 的类型。你可能会想到creating a Minimal, Complete, and Verifiable example 你的问题。如果你很幸运,这个例子可以让你自己解决问题,最坏的情况是你会增加别人帮助的机会。
  • lbStatus 将是一个列表框,问任何匈牙利人:)

标签: c# multithreading tcpclient tcplistener


【解决方案1】:

作为更新,我删除了所有与 GUI 通信的线程,并且 GUI 停止锁定。所以这证明这不是 GUI 线程问题。我研究了这些线程,直到我发现 TCPSender 线程有很多异步回调函数,可能有数百个。当这个线程忙于它的异步调用时,GUI 就会锁定。我怀疑这与线程正在处理 GUI 的方法之一时发生的回调有关。

我已经通过创建一个新线程解决了这个问题,该线程只从操作线程收集数据,然后更新用户界面。传输到 GUI 线程上的状态显示的一般状态消息现在排队并通过这个新线程更新到 GUI。

GUI 保持响应,实际上现在似乎能够显示更多数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 2023-03-21
    相关资源
    最近更新 更多