线程中Threading.Timer和Timer之间的区别

时间:2014-08-05 06:07:22

标签: c# .net multithreading winforms

之间有什么区别吗?

System.Threading.Timer

System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback(PerformAction), null, 0, 15000);

在新线程中使用System.Timers.Timer?

Thread thread = new Thread(new ThreadStart(PerformActionWithTimer));
thread.Start();

void PerformActionWithTimer()
{
   //Timer inside this
}

3 个答案:

答案 0 :(得分:2)

没有System.Windows.Timer这样的东西。大概你的意思是System.Windows.Forms.Timer。不要尝试在多线程场景中使用该类。它在UI线程上引发了它的Tick事件,就是这样。如果您希望计时器在辅助线程上引发事件,请使用System.Timers.Timer。没有真正的理由直接使用System.Threading.Timer

答案 1 :(得分:2)

我强烈建议您使用System.Timers.Timer,这主要是由于MSDN documentation中“备注”部分提供的一些信息。

  

Timer组件捕获并抑制事件处理程序为Elapsed事件抛出的所有异常。

这意味着如果你的计时器已经过去的事件引发了一个你没有明确捕获的异常,那么异常将被吞噬,你永远不会知道发生了什么不好的事。

考虑这个Elapsed事件处理程序:

static void MyTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Console.WriteLine("Badness! Throwing exception");
    throw new ApplicationException("something bad happened");
}

显然,这里的意图是立即终止程序,因为它遇到了不可恢复的错误。但异常永远不会逃到主程序。 .NET中的计时器处理程序基本上是这样的:

try
{
    MyTimer_Elapsed(sender, args);
}
catch
{
    // Why would anybody want to know that something bad happened?
}

这是一个隐藏的错误,因此我不会使用它。

此外,无法指定将在事件参数中提供的上下文对象,例如Windows窗体计时器(Tag属性)或System.Threading.Timer (传递给构造函数的state参数)。

System.Timers.Timer是围绕System.Threading.Timer的破坏且有限的组件包装器。它的两个便利点(组件包装器和SynchronizingObject)远远超过了它的愚蠢异常吞咽和缺少用户上下文对象。不要使用它。请改用System.Threading.Timer

答案 2 :(得分:1)

这取决于。 System.Timers.Timer有两种操作模式。

如果SynchronizingObject设置为ISynchronizeInvoke实例,则Elapsed事件将在托管同步对象的线程上执行。通常,这些ISynchronizeInvoke实例都是我们熟悉的普通旧ControlForm实例。因此,在这种情况下,在UI线程上调用Elapsed事件,它的行为类似于System.Windows.Forms.Timer。否则,它实际上取决于所使用的特定ISynchronizeInvoke实例。

如果SynchronizingObject为null,则在Elapsed线程上调用ThreadPool事件,其行为类似于System.Threading.Timer。事实上,它实际上在幕后使用了System.Threading.Timer,并在收到定时器回调后进行编组操作。

在您的特定情况下,您创建的System.Timers.Timer没有分配同步对象,因此它的行为与System.Threading.Timer相同。