【发布时间】: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 线程。在某种程度上我猜是因为我们不知道this和lbStatus的类型。你可能会想到creating a Minimal, Complete, and Verifiable example 你的问题。如果你很幸运,这个例子可以让你自己解决问题,最坏的情况是你会增加别人帮助的机会。 -
lbStatus 将是一个列表框,问任何匈牙利人:)
标签: c# multithreading tcpclient tcplistener