2011-10-12 72 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。

謝謝您的意見。

相關問題