2011-06-09 176 views
0

我有一个计时器事件,每秒触发。有时当我退出程序(在VS调试器中)时,它告诉我事件线程正试图访问不再存在的对象(因为主线程已结束)。我在退出之前尝试禁用该事件(UpdateTime.aTimer.Enabled = false;)。这样可以减少发生此问题的次数,但有时会发生这种情况,因为事件在我禁用之前会触发。杀死事件线程

  1. 这是一个严重的问题?如果我不处理它,Will会困扰我吗?
  2. 如果对上述是,我该如何杀死它?

我问第二个问题,因为我没有参考事件线程,所以我不知道如何告诉它停止或等待它完成。

编辑:更多的上下文。这是一个Winform。

此外,我没有明确创建一个线程。这是我的理解,一个线程是自动创建来处理事件。

创建定时器:

public static void Update(){ 

    System.Timers.Timer aTimer = new System.Timers.Timer(1000); 
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); 
    aTimer.Enabled = true; 

} 

事件处理程序:

private static void OnTimedEvent(object source,ElapsedEventArgs e) { 

    Form1obj.updateLabel(String.Format("{0}", DateTime.Now.Second),Label1); 

} 

关闭程序处理程序:

private void Form1_FormClosing(object sender,FormClosingEventArgs e) { 

    aTimer.Enabled = false; 

} 

回答

3

严重的问题?可能不会,但我认为一个问题不需要认真解决。例如,警告在编译时应被视为错误。另外,如果这是发送给客户端的应用程序,则在关机时显示丑陋的错误并不是很专业。

如何解决这个问题取决于你如何设置线程(“事件线程”没有提供关于机制的足够信息)。一个简单的方法可能是在应用程序关闭时停止主线程,直到线程全部返回。在此期间,您还必须停止发布新线程。

另一个可能的解决方案是处理线程的创建方式,以便关闭启动它们的进程。想到像ThreadPool这样的概念。确保线程是后台线程,明确地说,可以在某些情况下提供帮助。

简短的回答是没有人会给你一个坚定的“这将解决你的问题”的答案,没有你在你的代码中做什么的背景。

增加:

有一对夫妇的“快,降浊”的方式来处理这个问题。没有足够的时间进行全面的分析,所以看看它们是否有效。

  1. 通过等待
  2. 添加计数器,等到加下来就改正错误

我会考虑的是增加一个安全网,而不是当处于关机状态更新标签的第一件事。这与其他任何事情无关,因为这是你的错误发生的地方。我不认为“主要思路是不存在”是问题的核心,而这条线:

Form1obj.updateLabel(String.Format("{0}", DateTime.Now.Second),Label1); 

你怎么能更新的东西,不再存在?是的,这是在主线程上,所以在技术上...

一个简单的等待会是这样的:

private void Form1_FormClosing(object sender,FormClosingEventArgs e) 
{ 
    aTimer.Enabled = false; 
    Thread.Sleep(5000); 
} 

隐藏形式也未尝不可,因此用户并不认为这是?

如果您想使用更多“类似COM的方法”,您可以添加一个计数器。 Update()(当事件被触发时)时递增,OnTimedEvent()时递减。确保在更改计数器时锁定计数器,以免两个线程在同一毫秒内更改计数器。然后您可以等到计数器为0以完成关闭或应用程序卸载。

再次,这些是快速,简单和肮脏的方法,但它们可以帮助您避免错误。我相信有更多时间的人可以想出更优雅的解决方案。

0

这个问题很难给出一个普遍的问题,如果问题严重的话,这取决于计时器在做什么。它是什么样的计时器?一个系统。对一个或一个UI定时器进行线程化?

如果可能的话,尝试并重构代码,以便您可以告诉定时器停止触发,如果仅仅是为了不让用户误解错误信息。它可以像使用共享变量或(最好)一样简单CancellationToken

1

您可以关闭该窗口as suggested in MSDN - 当你设置定时关机处理过程中被禁用,设置你的Elapsed事件处理程序可以检查标志知道不需要更多的工作。

经过的事件 处置或停止方法后,可能会出现被称为 或Enabled属性后一直 设置为false,因为信号 抬高经过的事件总是 排队等待执行上线程池 线程。解决此种族的一种方法 条件 是设置一个标志,告知事件 处理程序为Elapsed事件为 忽略后续事件。