我想从工作线程修改计时器的间隔值,该计时器是System.Microsoft.Timer的实例 当我在线程运行的工作线程中更改此值时,Timer停止。
让我看看我的源代码
private void Scan_Screen(object sender, EventArgs e)
{
textBox1.Text += "a";
}
private void button1_Click(object sender, EventArgs e)
{
g_RECEIVER_timer = new System.Windows.Forms.Timer();
g_RECEIVER_timer.Enabled = true;
g_RECEIVER_timer.Interval = TIMER_INTERVAL;
g_RECEIVER_timer.Tick += new EventHandler(Scan_Screen);
}
private void button2_Click(object sender, EventArgs e)
{
g_Control_Thread = new Thread(new ParameterizedThreadStart(Control_Message_Receiver));
g_Control_Thread.Start(200);
}
//thread function
public void Control_Message_Receiver(object v)
{
g_RECEIVER_timer.Stop();
g_RECEIVER_timer.Interval = 200;
g_RECEIVER_timer.Enabled = true;
g_RECEIVER_timer.Tick += new EventHandler(Scan_Screen);
}
为什么会发生这种情况?另外我怎么能跑这个? (我想在工作线程中调整计时器的间隔值)
答案 0 :(得分:0)
您需要在UI线程上调用此Control_Message_Receiver
,因为您已经生成了另一个工作线程,并且您正在访问UI线程上下文中的对象。
并且不需要在工作线程方法上重新声明Tick事件。
请看下面的这个片段:
private void Scan_Screen(object sender, EventArgs e)
{
textBox1.Text += "a";
}
private void button1_Click(object sender, EventArgs e)
{
g_RECEIVER_timer = new System.Windows.Forms.Timer();
g_RECEIVER_timer.Enabled = true;
g_RECEIVER_timer.Interval = 1000;
g_RECEIVER_timer.Tick += new EventHandler(Scan_Screen);
}
private void button2_Click(object sender, EventArgs e)
{
Thread g_Control_Thread = new Thread(new ParameterizedThreadStart(Control_Message_Receiver));
g_Control_Thread.Start(1);
}
//thread function
public void Control_Message_Receiver(object v)
{
//timer1.Stop(); //why stop? -- remove this instead
IntervalChange((int)v); //call this method and invoke it on the UI thread
g_RECEIVER_timer.Enabled = true;
//timer1.Tick += new EventHandler(Scan_Screen); // -- remove this
}
delegate void intervalChanger(int time);
void ChangeInterval(int time)
{
g_RECEIVER_timer.Interval = time;
}
void IntervalChange(int time)
{
this.Invoke(new intervalChanger(ChangeInterval), new object[] {time}); //invoke on the UI thread
}
答案 1 :(得分:0)
使用System.Threading.Timer可能更好。这个可以从任何线程重新调整。但请注意,计时器回调在线程池线程中运行。因此,如果需要从此回调访问GUI,则必须使用Invoke。