加速线程的实时Gui更新
本文关键字:Gui 更新 实时 线程 加速 | 更新日期: 2023-09-27 17:52:38
这是我多年来一直使用的一种技术,用于接收网络数据并将其用于我的GUI(对话框,表单等)。
public delegate void mydelegate(Byte[] message);
public ReceiveEngineCS(String LocalIpIn, String ReceiveFromIp, mydelegate d)
{
this.m_LocalIpIn = LocalIpIn;
this.m_ReceiveFromIp = ReceiveFromIp;
m_MainCallback = d;
SetupReceive();
m_Running = true;
//Create the Track receive thread and pass the parent (this)
m_RtdirReceiveThread = new Thread(new ParameterizedThreadStart(MessageRecieveThread));
m_RtdirReceiveThread.Start(this);
}
private void MessageRecieveThread(System.Object obj)
{
ReceiveEngineCS parent = (ReceiveEngineCS)obj;
while(parent.m_Running)
{
Byte[] receiveBytes = new Byte[1500];
try
{
receiveBytes = parent.m_ClientReceiver.Receive(ref parent.ipEndPoint);
parent.ThreadOutput(receiveBytes);
}
catch ( Exception e )
{
parent.StatusUpdate(e.ToString());
}
}
}
public void ThreadOutput(Byte[] message)
{
m_MainCallback(message);
}
public partial class SystemMain : Form
{
//Local Class Variables
Network.ReceiveEngineCS SystemMessageReceiver;
private void Form1_Load(object sender, EventArgs e)
{
//Load up the message receiver
SystemMessageReceiver = new Network.ReceiveEngineCS(localAddy, fromAddy, new mydelegate(LocalDelegate));
}
public void LocalDelegate(Byte[] message)
{
if (Form.ListView.InvokeRequired)
{
//External call: invoke delegate
Form.ListView.Invoke(new mydelegate(this.LocalDelegate), message);
}
else
{
//Get the Packet Header
Formats.PacketHeaderObject ph = new Formats.PacketHeaderObject(message);
//Update or Add item to Specific ListView
... update views
}
}
}
接收器每秒钟接收10到100条实时消息,有时更多。
我最近一直在研究。net 4.0和c#,并注意到许多其他类似的数据处理方法例如Worker线程,以及其他使用Delegate和Invoke的方法。
我的问题…在较新的。net库(3.5,4.0等)中是否有更有效的方法来完成数据接收/GUI更新?
我认为这个方法在c#中不能很好地工作。
向GUI发布更新的最佳方法之一是让工作线程将更新中包含的数据打包并将其放置在队列中。然后UI线程将定期轮询队列。在我看来,让工作线程使用Control.Invoke
来更新UI是方式过度使用。相比之下,让UI线程轮询更新有几个优点。
- 它打破了
Control.Invoke
强加的UI和工作线程之间的紧密耦合。 - 它把更新UI线程的责任放在UI线程上,而UI线程本来就应该属于它。
- UI线程决定更新的时间和频率。
- 不存在UI消息泵溢出的风险,这可能是由工作线程发起的封送处理技术的情况。
- 工作线程在继续下一步之前不必等待更新被执行的确认。你可以在UI和工作线程上获得更多的吞吐量)。
你没有提到ThreadOutput
是如何实现的,但你可以考虑我上面提到的方法,如果它还没有这样做。经验告诉我,这通常是最好的方法。让UI线程控制其更新周期是一个很大的优势。
看看线程池,而不是每次都旋转新线程