C# 防止这种不安全的交叉线程
我有以下代码:C# 防止这种不安全的交叉线程,c#,multithreading,C#,Multithreading,我有以下代码: private void Form1_Load(object sender, EventArgs e) { /*start update timer*/ System.Timers.Timer updateticker = new System.Timers.Timer(); updateticker.Elapsed += new ElapsedEventHandler(update_ove
private void Form1_Load(object sender, EventArgs e)
{
/*start update timer*/
System.Timers.Timer updateticker = new System.Timers.Timer();
updateticker.Elapsed += new ElapsedEventHandler(update_overload);
//10 minute ticker
updateticker.Interval = 600000;
//30 sec ticker
updateticker.Interval = 30000;
updateticker.Enabled = true;
System.Timers.Timer guiTimer = new System.Timers.Timer();
guiTimer.Elapsed += new ElapsedEventHandler(idle_display);
//1 minute ticker
guiTimer.Interval = 60000;
//30 sec ticker
//updateticker.Interval = 30000;
guiTimer.Enabled = true;
}
//run front end idle timer
public void idle_display(object source, ElapsedEventArgs e)
{
if (minutes_left > 0) {
minutes_left = minutes_left - 1;
}
lbl_dyn_status.Text = "Time until next automatic update: "+ minutes_left + " minutes.";
}
Visual studio将第二个函数的最后一行标记为不安全的跨线程。有人能建议我如何重写这个来解决这个问题吗
干杯使用
System.Windows.Forms.Timer
而不是System.Timers.Timer
或使用计时器的属性
当SynchronizingObject为null时,将对系统线程池中的线程调用处理已用事件的方法。有关系统线程池的更多信息,请参阅线程池
当由可视Windows窗体组件(如按钮)处理已用事件时,通过系统线程池访问该组件可能会导致异常或无法工作。通过将SynchronizingObject设置为Windows窗体组件来避免此影响,这会导致在创建组件的同一线程上调用处理已用事件的方法
使用System.Windows.Forms.Timer Timer而不是System.Timers.Timer。如其他人所建议的,使用。与在线程池线程上操作不同,它保证在UI线程上调用tick事件 UI线程是唯一允许修改UI的线程。这就是为什么尝试写入
lbl\u dyn\u状态时会出现异常。Text
将处理程序更改为
public void IdleDisplay(object source, ElapsedEventArgs e)
{
if (lbl_dyn_status.InvokeRequired)
{
this.Invoke(IdleDisplay)
}
else
{
if (minutes_left > 0)
{
minutes_left = minutes_left - 1;
}
lbl_dyn_status.Text = string.Format(
"Time until next automatic update: {0} minutes.",
minutes_left);
}
}
这种方式允许您使用无线程的System.Threading.Timer
,但会检查处理程序中的跨线程调用。如果检测到调用,则通过表单
类在主GUI线程上调用
这是描述的
更一般地说,您不应该像这样使用计时器来计算时间。计时器的线程绑定越多,就越有可能偏离实际运行时间。您可以使用计时器计划时钟的更新,但是,您应该计算从某个固定点开始经过的时间,而不是使用迭代计数器。system.timers.timer如果不能与用户交互,它的用途是什么?它对任何没有用户交互的情况都很有用,例如,在windows服务中定期运行操作。正如我在回答中所述,像这样迭代地计算时间是个坏主意。