我有一个我编写的c#Win Forms应用程序,它有两个线程 - 主线程(GUI)和一个可以每隔x秒(心跳)响应服务器的线程。 但是当我在主线程上运行一些代码(删除标签,处理东西)时,gui没有响应,并且线程没有发送心跳 - 我做错了什么? 谢谢:))
线程是这样创建的:
thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
thrMessaging.Start();
并且实际上是一个负责从服务器获取所有消息的线程 - 就像这样:
private void ReceiveMessages()
{
// Receive the response from the server
srReceiver = new StreamReader(tcpServer.GetStream());
while (Connected)
{
// Show the messages in the log TextBox
//this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });
try
{
String con = srReceiver.ReadLine();
string StringMessage = HttpUtility.UrlDecode(con, System.Text.Encoding.UTF8);
//MessageBox.Show("MESSAGE TRANSLATED:" + StringMessage);
processMessage(StringMessage);
}
catch (IOException e)
{
connectionTerminated();
}
}
}
因为我需要procesMessage函数来执行某些UI任务,所以它是这样的:
private void processMessage(string p)
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(delegate
{
lastMessage = DateTime.Now;
//MessageBox.Show(p);
if (p == "AREYOUALIVE")
{
SendMessage("ye");
}
else if
......
}));
}
}
因此线程应始终响应(每x秒)来自服务器的消息,询问他是否还活着 - 在他进行处理时没有发生什么。
答案 0 :(得分:2)
您可以使用Control.BeginInvoke
(非阻止)(检查链接)而不是Control.Invoke
(阻止)。
http://www.yoda.arachsys.com/csharp/threads/winforms.shtml
据我所知,这两种方法都将Windows消息传递给UI队列,Invoke
使用 SEND 发送消息,阻止直到获得结果,BeginInvoke
使用 POST ,即可立即返回。
答案 1 :(得分:0)
我认为问题可能是这样的:当你调用调用时,GUI更新是由主线程(GUI一个)进行的...所以如果你的主线程忙于做其他事情(删除控件(例如))无法立即处理此任务,锁定执行...
答案 2 :(得分:0)
这很简单,如果你通过
编组到UI线程就会发生这种情况Invoke(new MethodInvoker(delegate...
我可以建议您使用来自服务器的消息创建一个队列,并通过计时器在另一个线程中处理此队列大约2或3秒,它将更快地工作,并且处理来自服务器的消息的后台线程永远不会挂起。
主要思想是不像现在那样经常更新UI。