2016-06-21 93 views
-1

我一直在研究WinForms实用程序,该实用程序从文本文件获取命令和/或数据,并基于此文件的内容通过串行传输或请求更多数据。这一切都很完美,但我正在努力研究如何让GUI给出一些反馈,指出发生了什么。在其目前的结构形式主要负载和Load()事件打开文本文件,并处理其内容线程和更新GUI

tp = new TProcess(); 
tp.FileOpen(); 

T加工和所有参与串口通信的其它类被收集到一个子项目,编译如下一个DLL。反过来,TProcess将创建SerialDevice对象的新实例(也在我的DLL中定义),并将其传递给我的数据,然后告诉它如何处理它,例如

//TProcess 


if (File.Exists(filey)) 
      try 
       { 

       StreamReader file = new StreamReader(@"filey"); 



       List<clsStuff> stuffList = new List<clsStuff>(); 

       while ((line = file.ReadLine()) != null) 
        { 
        //process and add to list 
        } 

        var SD = new SerialDevice(); 
        SD.List = stuffList;       
        SD.Send(); 

       file.Close(); 

       } 
      catch (Exception e) 
       { 
       //Write Error File 

       } 

     } 

我的SD类定义了所有的端口参数,将第一项的数据包,并接收确认来自使用DataReceived事件检索远程设备分组时,它然后在一时间发送从所述列表中的一个项目,直到它有完成并退出。 因此,我的问题(对不起长时间啰嗦)是我怎么能通过某种反馈(可能是每次我收到一个数据包确认后收到Record X的字符串)事情发生在GUI上,因为GUI线程没有创建我的SD实例,如果这是一个更紧凑的程序,并且GUI线程已经调用SD,我将使用委托和BeginInvoke,但是我不明白我在这里如何做到这一点,因为GUI对SD实例一无所知,同样,SD也不知道关于GUI。我觉得这可能通过SynchronisationContext解决,但我不知道如何实现它。

  public void Send() 
       { 
       if (!serialP.IsOpen) 
        { 
        PortOpen(); 
        serialP.ReceivedBytesThreshold = 4; 
        } 
       serialP.Write(CurrentListItem, 0, 11); 


       } 
     private void serialP_DataEvent(object sender, SerialDataReceivedEventArgs e)// This triggers when the response is received 
       { 


         byte[] Ack = new byte[4]; 
         serialP.Read(Ack, 0, 4); 
         //snip of course I check these 4 bytes etc here 
           CurrentListItem++; 
           //UPDATE THE GUI BUT HOW? 
           Send()!;//next 
        } 
+0

* //更新GUI,但是如何使用您的视图也可以订阅的事件。但是它看起来像你对文件的处理是阻塞的(很难用你的代码片段来说明),所以你可能也想做出这种异步。 –

+1

请编辑您的问题并设置您的代码的格式,以便可读 –

+0

@sowjanyaattaluri:存在事件,因此您不必这样做。 –

回答

0

要将TProcess类添加您的UI可以订阅一个事件:

public event EventHandler DataRecieved; 

然后在你的serialP_DataEvent你可以在适当的时候做的事:

if (DataRecieved != null) 
{ 
    DataRecieved(this,EventArgs.Empty); 
} 

你的UI可以再订阅此:

tp.DataRecieved += (o,e) => { // do something to the UI }; 

有两点要注意:

1)你可以,如果你使用的是一般EventHandler<T>代替EventHandler事件传递信息。其中T是您想要发送的任何数据的类别

2)它看起来像FileOpen是同步和阻止,因此它会阻止您的用户界面更新。使其异步或至少使用Task.Run

3)如果你让它是异步的,你可能会遇到尝试从不是UI线程的线程更新UI的问题。您将需要使用Invoke将UI更新推回UI线程(您不会说这是WinForms还是WPF,但它们是相似的)。

+0

谢谢,我确实相信你正确地指向我想要去的地方,并且也感谢文件处理提示,这是我在列表中的下一个东西,在行之间插入延迟会阻止表单加载。 – BinBin

+0

好吧,我决定一次完成这一步,所以我制作了一个不那么复杂的项目(没有文件处理),其中SerialDevice类为UI描述了一个事件,并描述了它然后使用Invoke来更新文本字段,作品。我可能是愚蠢的,但我然后把我的注意力再次处理文件,我的SerialDevice类如何触发创建它的TProcess类中的DataReceived事件?我是否菊花链事件,所以TProcess订阅由SerialDevice提供的事件? – BinBin