如何将一个计时器连接到不同的线程事件
问题描述:
我有一个应用程序,我必须让一些leds闪烁一些颜色和(调试)一个椭圆。根据事件驱动的状态,我必须改变眨眼的颜色。 计时器始终是相同的:如何将一个计时器连接到不同的线程事件
DispatcherTimer ledTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) };
但根据ledState值其行为变化。而且那个根据外部事件而改变。
public eLedState _ledState;
EventHandler ehLedTimer = null;
eLedState LedState
{
get { return _ledState; }
set
{
ledTimer.Stop();
ledTimer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) };
if (ehLedTimer != null)
ledTimer.Tick -= ehLedTimer;
int counter = 0;
_ledState = value;
string WHITE = "255,255,255,1,0";
string GREEN = "0,255,0,1,0";
string RED = "255,0,0,1,0";
string BLUE = "0,0,255,1,0";
string YELLOW = "255,255,0,1,0";
string OFF = "0,0,0";
Serializers.Logger.WriteLog("LedState = " + LedState);
switch (_ledState)
{
case eLedState.IDLE: SetLeds(WHITE); break;
case eLedState.CONNECTING:
ehLedTimer = (sender2, args) =>
{
switch (counter)
{
case 0: SetLeds(RED); counter++; break;
case 1: SetLeds(GREEN); counter++; break;
case 2: SetLeds(BLUE); counter = 0; break;
}
};
break;
case eLedState.RUNNING:
ehLedTimer = (sender2, args) => { SetLeds(YELLOW); }; <-----HERE PROBLEM
break;
case eLedState.OUT_TOLERANCE:
ehLedTimer = (sender2, args) =>
{
switch (counter)
{
case 0: SetLeds(RED); counter++; break;
case 1: SetLeds(WHITE); counter = 0; break;
}
};
break;
case eLedState.IN_TOLERANCE:
ehLedTimer = (sender2, args) =>
{
switch (counter)
{
case 0: SetLeds(GREEN); counter++; break;
case 1: SetLeds(WHITE); counter = 0; break;
}
};
break;
case eLedState.PAUSED:
ehLedTimer = (sender2, args) =>
{
switch (counter)
{
case 0: SetLeds(WHITE); counter++; break;
case 1: SetLeds(OFF); counter = 0; break;
}
};
ledTimer.Start(); break;
case eLedState.ERROR:
ledTimer.Tick += (sender2, args) =>
{
switch (counter)
{
case 0: SetLeds(RED); counter++; break;
case 1: SetLeds(OFF); counter = 0; break;
}
};
break;
case eLedState.AWAITING_AUTOSTART:
ledTimer.Tick += (sender2, args) =>
{
switch (counter)
{
case 0: SetLeds(RED); counter++; break;
case 1: SetLeds(GREEN); counter = 0; break;
}
};
break;
default:
break;
}
ledTimer.Tick += ehLedTimer;
ledTimer.Start();
}
}
因此,在短期我的想法是:当变化来检测站前面的计时器行为,改变它,恢复和启动。
但有些东西不行。它行为怪异,试图更具体,它永远不会变黄。
如果我在ledstate设置为正在运行的位置放置一个断点,我会发现它已被击中但从未进入SetLeds例程。这种运行状态是从另一个线程设置的,这可能是原因吗?
因此,简而言之,当运行事件被触发时,定时器不打勾。
预先感谢您的任何帮助
帕特里克
答
尝试把一个破发点,在其他一些点在你的代码&然后检查ledTimer.Dispatcher.Thread &你可能会看到“此.ledTimer.Dispatcher.Thread.ApartmentState'抛出了一个'System.Threading.ThreadStateException'类型的异常。
您需要设置在同一个线程的新状态的定时器的归属 - 你可以得到定时器与它自己的调度员设置(或GUI线程上任何其他对象):
ledTimer.Dispatcher.Invoke(() => LedState = eLedState.RUNNING);
当LedState setter在另一个线程中调用,DispatcherTimer与该线程的关联创建。然后它会在该线程中调用它的Tick处理程序,这不是UI线程,因此无法访问任何代表LED的UI元素。除此之外,我觉得你的方法太复杂了。为什么不简单评估一个Tick处理程序的每次调用中的LedState属性?它根本不需要任何性能。 – Clemens
非常感谢。你的提示使我找到了正确的解决方案。你可能想把它作为答案发布...... – Patrick