2011-10-12 50 views
1

我正在写一个软件,通过串行端口与4个设备进行通信。其中一个输入/输出模块(ICP CON)具有4个输入通道(DL)和4个输出通道(RL)。我需要监视DL通道的状态,然后当检测到信号时,我必须做一些处理,这取决于检测到哪个信号。delegate.Invoke和delegate.BeginInvoke - 使用相同的方法,返回两个不同的结果

我打电话的4种方法异步,每500ms(定时器),这里的蜱事件:

//stop the timer 
timer1.Stop(); 

//open com port 2 
Tester.Devices.ICP.OpenICPPort(2, 9600); 

//dl 0 
ic = new CheckDLStatus(0, this); 
ic.Execute(); 

//dl 1 
ic = new CheckDLStatus(1, this); 
ic.Execute(); 

//dl 2 
ic = new CheckDLStatus(2, this); 
ic.Execute(); 

//dl3 
ic = new CheckDLStatus(3, this); 
ic.Execute(); 

//close com port 2 
Tester.Devices.ICP.CloseICPPort(2); 

//enable the timer again 
timer1.Enabled = true; 

public CheckDLStatus(int DL, Form1 F1) 
{ 
    //form 1 instance 
    f1 = F1; 

    // setup the delegate to call 
    switch (DL) 
    { 
     case (0): 
     { 
      checkDL_delegate = new checkDL(
       BusinessLogicLayer.Classes. 
       DevicesCommunication.CheckDl0); 

      break; 
     } 
     case (1): 
     { 
      checkDL_delegate = new checkDL(
       BusinessLogicLayer.Classes. 
       DevicesCommunication.CheckDl1); 

       break; 
     } 
     case (2): 
     { 
      checkDL_delegate = new checkDL(
       BusinessLogicLayer.Classes. 
       DevicesCommunication.CheckDl2); 

       break; 
     } 
     case (3): 
     { 
      checkDL_delegate = new checkDL(
       BusinessLogicLayer.Classes. 
       DevicesCommunication.CheckDl3); 

       break; 
     } 
    } 
} 


public static void CheckDl2() 
{ 
    //declare 
    bool currentStatus; 

    try 
    { 
     //input 
     currentStatus = DevicesCommunication.Dl_2_On; 
     //should be false at the start of the test, 
     //so when it becomes true, the change is detected immediately 

     //dl2? 
     if (ICP.LookForSignal_DL2((short)2, 
      Util.Classes.Util.ResolveComPortNumber(
       Cache.settings.icpModulePort),  
      Convert.ToInt32(Cache.settings.icpModuleBaudRate))) 
     { 
      //signal detected 
      DevicesCommunication.Dl_2_On = true; 
     } 
     else 
     { 
      //signal not detected 
      DevicesCommunication.Dl_2_On = false; 
     } 

     //check, if status of DL2 has been changed 
     //(from true to false, from false to true) 
     if (currentStatus != DevicesCommunication.Dl_2_On) 
     { 
      //status from before checking signal is different 
      // from status read from the device so 
      //status has changed 

      if (DevicesCommunication.Dl_2_On) 
      { 
       DevicesCommunication.DL2_apperancesCounter += 1; 

       //TODO 
       //process 
       //ProcessDL2(); 
      } 
     } 
     else 
     { 
      //status did not change 
      //just clear buffer 
      ClearBuffer(); 
     } 

     return; 
    } 
    catch (Exception ex) 
    { 
     Util.Classes.ErrorLogging.LogError(ex, true); 
     //EndCurrentTest(); 
     return; 
    } 
} 

Execute()方法,调用一个委托:

public void Execute() 
{ 
    // call the method on the thread pool 
    checkDL_delegate.BeginInvoke(
     this.CallBack, null); 

    //checkDL_delegate.Invoke(); 
} 

的方法被称为检查DL2状态:

public static bool LookForSignal_DL2(short DL_number, int port, int baudRate) 
{ 
    //declare 
    bool iBit; 

    try 
    { 
     //check if there is a signal at specified Dl_number 
     iBit = DCON.Read_DI_Bit(Convert.ToByte(port), 1, -1, 
      DL_number, 16, 0, 100); 

     //return resposne 
     return iBit; //true/false 
    } 
    catch (Exception ex) 
    { 
     Util.Classes.ErrorLogging.LogError(ex, true); 
     return false; 
    } 
} 

我的问题是,当我打开D L2通道,我称之为​​这样的,没有定时器和异步调用(只是为了测试):

private void button25_Click(object sender, EventArgs e) 
{ 
    ICP.OpenICPPort(2, 9600); 

    if (ICP.LookForSignal_DL2(2, 2, 9600)) 
    { 
     MessageBox.Show("True"); 
    } 
    else 
    { 
     MessageBox.Show("false!"); 
    } 

    ICP.CloseICPPort(2); 
} 

它的工作原理 - 返回true。

如果在Execute()方法中我使用Invoke,它使得方法调用同步 - 它工作(返回true),但是这样我只能在此时检查1个信号。

如果在Execute()方法中使用BeginInvoke它不起作用,即使在DL2中有信号,它也会返回false。

我承认我不知道发生了什么事。你有什么主意吗?

+3

什么是'this.Callback'? –

+0

private void CallBack(IAsyncResult ar) { checkDL_delegate.EndInvoke(ar); updateStatus_delegate = new updatestatus(f1.UpdateDLStatus);如果(f1.InvokeRequired) { f1.Invoke(updateStatus_delegate);(f1.InvokeRequired) } else { f1.UpdateDLStatus(); } } – MSporna

+0

“CheckDLStatus”方法有什么作用?如果你可以更新你的问题来包含所有你打电话的代码,它会*真的*有帮助。 –

回答

0

我想通了,如果有帮助的人,我在这里做了一个错误(粗体文本):

//stop the timer 
timer1.Stop(); 

//open com port 2 
Tester.Devices.ICP.OpenICPPort(2, 9600); 

//dl 0 
ic = new CheckDLStatus(0, this); 
ic.Execute(); 

//dl 1 
ic = new CheckDLStatus(1, this); 
ic.Execute(); 

//dl 2 
ic = new CheckDLStatus(2, this); 
ic.Execute(); 

//dl3 
ic = new CheckDLStatus(3, this); 
ic.Execute(); 

Tester.Devices.ICP.CloseICPPort(2);

我异步运行我的方法,但代码的执行继续进行,并且每次在任何方法都能够检查信号之前端口已关闭。不幸的是,SDK库在这种情况下不会返回任何错误,所以它只是不断返回false。

谢谢您的意见。

相关问题