C# 计时器可以安全地丢弃吗

C# 计时器可以安全地丢弃吗,c#,.net,multithreading,timer,C#,.net,Multithreading,Timer,在不调用Dispose()或Close()的情况下放弃.NET中的计时器是否安全 有人看到这个解决方案有什么问题吗 static QueueLogger() { LogQueue = new Queue<KeyValuePair<Logger, LogEntry>>(50); LogTimer = new Timer(); LogTimer.Elapsed +=new System.Timers.ElapsedEventHandler(LogTim

在不调用Dispose()或Close()的情况下放弃.NET中的计时器是否安全

有人看到这个解决方案有什么问题吗

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);
            }
        }
    }
}
staticqueuelogger()
{
LogQueue=新队列(50);
LogTimer=新计时器();
LogTimer.appeased+=新系统.Timers.ElapsedEventHandler(LogTimer\u appeased);
AppDomain.CurrentDomain.ProcessExit+=新事件处理程序(CurrentDomain\u ProcessExit);
}
静态无效CurrentDomain_ProcessExit(对象发送方,事件参数e)
{
LogTimer.Stop();
LogTimer.Dispose();
LogTimer_expressed(sender,null);//用于处理队列中的所有剩余消息
}
静态无效日志计时器(对象发送器,System.Timers.ElapsedEventArgs e)
{
锁(储物柜)
{
而(LogQueue.Count>0)
{
var queuedLogger=LogQueue.Dequeue();
尝试
{
如果(e!=null)queuedLogger.Value.Message+=“From”+sender.ToString();
queuedLogger.Key.Log(queuedLogger.Value);
}
捕获(例外情况除外)
{
OnLoggingError(queuedLogger.Key,“异步日志记录错误”,ex);
}
}
}
}

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

如果不明确处置计时器,它将在垃圾收集器的终结器队列中被清除。虽然这是“安全的”,但您将受到性能惩罚。最好从以下位置处置计时器。

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

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

来自:

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


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

如果不处理计时器,垃圾收集将清理计时器。如果计时器在.exe中,并且进程将在计时器结束时退出,那么您真的不必担心。如果您正在编写一个引用计时器的库,您可能希望将其处理掉以释放资源,从而使库更高效。

如果您不处理计时器,垃圾收集将清理它。如果计时器在.exe中,并且进程将在计时器结束时退出,那么您真的不必担心。如果您正在编写一个引用计时器的库,您可能希望将其处理为释放资源,以提高库的效率。

Galford

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

向加尔福德致意

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

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

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

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

在您提供的示例中,计时器变量似乎是静态的,并且绑定到主线程。看起来你也在使用计时器,直到程序结束。因此,在这种特定情况下,这并不重要。

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

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

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


在您提供的示例中,计时器变量似乎是静态的,并且绑定到主线程。看起来你也在使用计时器,直到程序结束。因此,在这种特定情况下,这真的不重要。

有没有办法知道应用程序是否正在退出?我的目的是编写一个库,它将使用计时器定期执行某些操作,但我不希望用户被要求处理和清理库中的任何内容。这会带来什么惩罚?@galford13x为什么不希望用户清理这些内容?那是t
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);
            }
        }
    }
}