可以安全地放弃计时器

时间:2012-02-04 15:46:04

标签: c# .net multithreading timer

如果不调用Dispose()或Close(),.NET中的计时器是否可以放弃?

static System.Timers.Timer timer = new Timer();

void Main()
{
    timer.Elapsed += LogTimer_Elapsed(object, System.Timers.ElapsedEventArgs);
    timer.Start();
    Thread.Sleep(10000); // Simulate doing something on main thread
}

static void LogTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    DoStuff();
}

有人发现此解决方案存在任何问题吗?

static QueueLogger()
{
    LogQueue = new Queue<KeyValuePair<Logger, LogEntry>>(50);
    LogTimer = new Timer();
    LogTimer.Elapsed +=new System.Timers.ElapsedEventHandler(LogTimer_Elapsed);
    AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
}

static void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
    LogTimer.Stop();
    LogTimer.Dispose();
    LogTimer_Elapsed(sender, null);  // This is to process any remaining messages in the queue
}

static void LogTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    lock (_locker)
    {
        while (LogQueue.Count > 0)
        {
            var queuedLogger = LogQueue.Dequeue();
            try
            {
                if (e != null) queuedLogger.Value.Message += " From " + sender.ToString();
                queuedLogger.Key.Log(queuedLogger.Value);
            }
            catch (Exception ex)
            {
                OnLoggingError(queuedLogger.Key, "Async Logging error", ex);
            }
        }
    }
}

5 个答案:

答案 0 :(得分:1)

如果您没有明确处理它,它将在垃圾收集器的终结器队列中清除。虽然这是“安全的”,但您会受到性能损失。最好丢弃你的计时器。

答案 1 :(得分:1)

来自http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

“当不再需要计时器时,使用Dispose方法释放计时器持有的资源。”

因此,如果您希望计时器一直运行到程序结束,那么您无需担心它。

答案 2 :(得分:1)

管理员加尔福特,

是的,您可以创建新的事件,如果您的应用程序即将退出,则会触发该事件。当应用程序的主线程即将关闭时,OnExit并监听事件。完成后,您可以创建事件逻辑并在OnExit事件中执行计时器,业务或清理逻辑。希望这会有所帮助。

此致

答案 3 :(得分:0)

如果您不处理它,垃圾收集将清理Timer。如果计时器在.exe中,并且当计时器结束时该过程将被退出,你真的不必担心。如果您编写一个库,其中将引用计时器,您可能希望将其处置为免费资源,以提高您的库的效率。

答案 4 :(得分:0)

调用Dispose()允许在垃圾回收器决定清理托管对象之前清理托管对象使用的非托管资源,在此操作期间还会清理非托管资源。

调用Dispose()通常是关于内存使用优化,但是,在某些情况下,不调用Dispose()实际上会导致软件无法正常运行。例如:由于以太网端口数量有限,因此在使用后不释放它们可能会导致系统耗尽网络端口。这通常称为“TCP / IP端口耗尽”,当您不在使用网络资源的托管对象(例如WCF客户端)上调用Dispose()时,可能会发生这种情况。

作为一般规则,当您不再需要任何类实现IDisposable的对象时,调用Dispose()总是一个明智的想法。 (或在using {}块中使用它。)

在您提供的示例中,似乎您的计时器变量是静态的,并绑定到主线程。您似乎也在使用计时器来结束程序。所以在这个特定情况下,它确实没关系。