2011-04-24 127 views
5

这加快实时更新桂是我已经使用多年接收网络数据,并在我的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 
     } 
    } 
} 

Receiver每秒接收10到100个实时消息,并且通常更多。

我一直在做研究最近到.NET 4.0和C#,发现许多其他类似的方式来做到这一点的数据处理 ,比如工作线程,并使用代表和调用的其他方式。

我的问题...有没有在新的.NET库(3.5,4.0等)更有效的方式这个数据接收/ GUI更新呢?

我觉得这个方法不使用C#的工作,以及。

任何帮助,将不胜感激。

+1

每秒向用户投掷100个通知没有多大意义。它看起来像模糊。先让你的UI可用,也解决你的问题。 Winforms没有变化。 – 2011-04-25 00:18:48

+0

好主意汉斯。如果我在线程中构建关于传入数据的元数据,并且每秒钟只更新gui,那么它仍然会给予用户有关数据的体面回应,同时允许Gui不会因更新而停滞不前。通常操作员使用更新数据项的粗略计数作为数据速率的指导。因此,一眼就可以计算出十秒一秒50等等。但我可以将它作为元更新并将其添加到列表视图中。 – Sleff 2011-04-25 02:53:47

回答

4

一个更新发布到GUI的最好的方法是让工作线程包了包含在更新的数据,并将其放置在队列中。 UI线程将定期轮询队列。有工作者线程使用Control.Invoke更新UI是方式在我看来过度使用。相比之下,让UI线程轮询更新有几个优点。

  • 它打破了用户界面和工作者线程之间的紧密耦合,这些线程与Control.Invoke强加。
  • 它将UI线程更新的责任置于UI线程上,无论如何它应该属于它。
  • UI线程可以决定更新应该发生的时间和频率。
  • 不存在UI消息泵被超载的风险,这与工作线程启动的封送处理技术的情况相同。
  • 工作线程不必等待确认该更新与它的下一个步骤之前执行(即你同时在用户界面和工作线程的详细吞吐量)。

你没有提到ThreadOutput是如何实现的,但你可以考虑我上面提到的,如果它尚未做到这一点的方式方法。经验告诉我,这通常是最好的方法。让UI线程节制其更新周期是一大优势。

+0

我一直用共享资源轮询数据的问题一直是时机之一。锁定和解锁共享队列会导致大量开销(当然,我不会遇到这个问题)。我查看了工作线程,发现有线程发送更新的机制。我不确定是否必须使用调用工作线程来更新拥有UI的队列? – Sleff 2011-04-25 03:05:02

+0

与'Control.Invoke'相比,队列的锁定是一件非常昂贵的操作。另外,你总是可以使用'ConcurrentQueue',它使用无锁机制。工作线程不必使用'Invoke'将某些东西发布到队列中。首先将其称为“UI拥有队列”可能有点误导。 – 2011-04-25 12:54:35

+0

这有助于@布莱恩。我不确定调用的费用。我一直看到它用于从简单文件或低速率xml数据更新gui的简单示例中。我将检查ConcurrentQueue,并考虑减少@Hans建议的需要更新的内容。 – Sleff 2011-04-25 16:27:40

1

看看到Thread Pooling而不是每次纺纱新的线程。

+0

谢谢赞博尼,但我实际上只使用一个线程的消息接收应用程序的整个生命周期。这些消息是我需要始终接收的事件的连续更新。 – Sleff 2011-04-25 02:46:39