Ok..this将会很长,但我需要先解释一些背景知识。
我的这部分软件是用来分拣从传送带上跑下来的物品的。我正在使用Modbus作为传送带。Modbus会在特定时间打开门,让物品通过门。物品会根据重量通过一定的闸门。
我正在监测一个传感器,以确定物品是否在天平上。当传感器被阻塞时,该物品被称重并被送到适当的闸门。定时器设置为打开/关闭闸门。
我的代码将工作的this..the问题是,它不会工作的多个项目。我的意思是,当门打开时,传感器不会被监控,直到门关闭。因此,当物品A在去登机口的路上,当物品B挡住传感器时,它不会在天平上称重。我一次最多可以有8个项目。下面是我现在运行的代码:
private void SensorThread_DoWork(object sender, DoWorkEventArgs e)
{
if (SensorThread.CancellationPending == true)
e.Cancel = true;
else
{
ReadSensor();
}
}
private void SensorThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//if sensor is blocked
if (sensorstatus == 0)
{
//the timers just start the thread
scaleTimer.Start();
}
else
{
sensorTimer.Start();
}
}
private void ScaleThread_DoWork(object sender, DoWorkEventArgs e)
{
if (ScaleThread.CancellationPending == true)
{
e.Cancel = true;
}
else
{
ReadScale();
//SaveWeight();
prevgate = gate;
gate = DetermineGate();
SetOpenDelay();
SetDuration();
}
}
private void ScaleThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//if gate = 0, this means the weight of meat on scale
//is not in any weight range. Meat runs off the end.
if (gate == 0)
{
txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() +
"lbs is out of range"});
sensorTimer.Start();
}
else
{
//open gate
//then close gate
}
}这段代码运行得很好,我只需要能够处理行上的多个项目。有什么建议吗?
我还尝试了以下几种方法:
private void SensorThread_DoWork(object sender, DoWorkEventArgs e)
{
if (SensorThread.CancellationPending == true)
e.Cancel = true;
else
{
ReadSensor();
}
}
private void SensorThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
sensorTimer.Start();
}
private void ScaleThread_DoWork(object sender, DoWorkEventArgs e)
{
if (ScaleThread.CancellationPending == true)
{
e.Cancel = true;
}
else
{
//sensor blocked
if (sensorstatus == 0)
{
ReadScale();
//SaveWeight();
prevgate = gate;
gate = DetermineGate();
SetOpenDelay();
SetDuration();
//if gate = 0, this means the weight of meat on scale
//is not in any weight range. Meat runs off the end.
if (gate == 0)
{
txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() +
"lbs is out of range"});
}
else
{
//open gate
//close gate
}
}
}
private void ScaleThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
scaleTimer.Start();
}当我这样做的时候,当按下start按钮时,我启动了两个线程。我得到了各种各样的异常,程序最终抛出了SEHException并崩溃。我得到的其他错误是“串行端口已经打开”或"I/O错误“。
发布于 2012-03-29 05:30:11
我想你需要这样的东西。我不知道是否需要这些锁,但为了安全起见,我添加了它们,因为您会收到错误
private void SensorThread_DoWork(object sender, DoWorkEventArgs e)
{
int sensor = 1;
while(!SensorThread.CancellationPending == true)
{
int newSensor;
lock(this)
{
newSensor = ReadSensor();
}
//sensor state changed
if(newSensor != sensor)
{
//sensor was 1 and changed to 0
if(newSensor==0)
{
scaleTimer.Start();
}
sensor = newSensor;
}
Thread.Sleep(1);
}
e.Cancel = true;
}
private void ScaleThread_DoWork(object sender, DoWorkEventArgs e)
{
//sensor blocked
//if (sensorstatus == 0)
{
lock(this)
{
ReadScale();
}
//SaveWeight();
prevgate = gate;
gate = DetermineGate();
lock(this)
{
SetOpenDelay();
SetDuration();
}
//if gate = 0, this means the weight of meat on scale
//is not in any weight range. Meat runs off the end.
if (gate == 0)
{
txtStatus.Invoke(new UpdateStatusCallback(UpdateStatus), new object[] { meatweight.ToString() +
"lbs is out of range"});
}
else
{
lock(this)
{
//open gate
}
lock(this)
{
//close gate
}
}
} 发布于 2012-03-29 04:34:40
我建议您最好的办法是在每个串行端口上创建一个专用线程。这样的方法既不需要也不禁止在如何处理端口方面有任何相似之处,将避免端口之间的任何操作干扰,并且将在合理的范围内可扩展( 32个端口中的每个端口使用一个线程就可以了;1000个端口中的每个端口使用一个线程就不好了)。虽然人们应该避免创建只会运行很短时间然后退出的线程,或者创建真正大量的线程,但为每个串行端口使用专用线程将确保当数据进入时,会有一个线程准备好处理它。
发布于 2012-03-29 04:35:42
我注意到您的线程的DoWork方法中没有任何循环。这将是一个很好的起点。工作线程应该是一个循环,在CancellationPending设置为true之前不会返回。它们不会仅仅因为您将其放在线程中而自行循环--线程将一直运行,直到完成,然后退出。
编辑后添加:您似乎缺少的是,您需要将监视规模的代码与打开和关闭门的代码分开。要做到这一点,一种方法是有一个无限循环来监控规模,当它检测到一些东西时,它会启动一个新的线程来处理门的打开和关闭。
https://stackoverflow.com/questions/9914948
复制相似问题