【发布时间】:2011-10-12 14:00:08
【问题描述】:
我正在编写一个通过串口与 4 个设备通信的软件。其中之一,输入/输出模块(ICP CON)有4个输入通道(DL)和4个输出通道(RL)。我需要监控 DL 通道的状态,然后,当检测到信号时,我必须进行一些处理,这取决于检测到的信号。
我正在异步调用 4 个方法,每 500 毫秒(定时器),这里是滴答事件:
//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;
}
}
我的问题是,当我打开 DL2 通道上的信号时,我像这样调用LookForSignal_DL2,没有定时器和异步调用(仅用于测试):
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 它不起作用,它返回false,即使DL2 中有信号。
我承认我不知道发生了什么。你有什么想法吗?
【问题讨论】:
-
什么是
this.Callback? -
private void CallBack(IAsyncResult ar) { checkDL_delegate.EndInvoke(ar); updateStatus_delegate = 新的更新状态(f1.UpdateDLStatus); if (f1.InvokeRequired) { f1.Invoke(updateStatus_delegate); } 其他 { f1.UpdateDLStatus(); } }
-
那么
CheckDLStatus方法的作用是什么?如果您可以更新您的问题以包含您正在调用的代码的所有,这将真正有所帮助。 -
BeginInvoke() 立即返回并且不阻塞,这意味着它不等待 DL2 信号并且 LookForSignal_DL2 返回 false。如果我错了,请告诉我。
-
当它在异步模式下返回 false .. 你的日志中是否记录了错误?我注意到您在错误时返回 false .. 可能会抛出异常,直到您找到它?我承认自从我做了串行端口的东西并且它在.net 2中已经有几年了......但我记得打开端口然后等待一个事件被触发,告诉我信号已经到达。您轮询端口的方法对我来说似乎有点奇怪..但是我不知道您的系统要求...只是想我会提一下,以防您采取复杂的路线来做一些简单的事情(就像我经常遇到的那样:) )
标签: c# asynchronous delegates timer