停车时同步一个Timers.Timer过去了方法方法、Timers、Timer

2023-09-04 00:41:59 作者:佯装执着

通过引用这句话从MSDN关于System.Timers.Timer的:

With reference to this quote from MSDN about the System.Timers.Timer:

该Timer.Elapsed事件引发上   线程池螺纹,所以   事件处理方法,可能会在一个运行   螺纹同时的呼叫到   该Timer.Stop方法运行在另一   线。这可能导致在   之后被提出经过的事件   停止方法被调用。这场比赛   条件不能为prevented简单   通过比较SignalTime属性   用时停止的方法是时间   叫,因为事件处理   方法可能已经在执行的时候   停止方法被调用,也可能   开始的那一刻之间执行   当停止方法被调用,   当停止时间被保存的时刻。如果   它是prevent线程关键   调用从停止方法   出发而事件处理   方法仍在执行,使用更   强大的同步机制等   为Monitor类或   CompareExchange方法。使用code   该CompareExchange方法可以   在实施例为所找到的   Timer.Stop方法。

The Timer.Elapsed event is raised on a ThreadPool thread, so the event-handling method might run on one thread at the same time that a call to the Timer.Stop method runs on another thread. This might result in the Elapsed event being raised after the Stop method is called. This race condition cannot be prevented simply by comparing the SignalTime property with the time when the Stop method is called, because the event-handling method might already be executing when the Stop method is called, or might begin executing between the moment when the Stop method is called and the moment when the stop time is saved. If it is critical to prevent the thread that calls the Stop method from proceeding while the event-handling method is still executing, use a more robust synchronization mechanism such as the Monitor class or the CompareExchange method. Code that uses the CompareExchange method can be found in the example for the Timer.Stop method.

谁能给的一个例子稳健的同步机制,如Monitor类来解释这是什么意思是什么呢?

Can anyone give an example of a "robust synchronization mechanism such as the Monitor class" to explain what this means exactly?

我想这意味着以某种方式使用锁,但我不能确定你将如何实现这一点。

I am thinking it means use a lock somehow, but I am unsure how you would implement that.

推荐答案

停止System.Timers.Timer的可靠的确是一个重大的努力。最严重的问题是,它用来调用经过的事件线程池的线程可以备份由于线程池调度算法。有一对夫妇备份电话是不寻常的,有数百个在技术上是可行的。

Stopping a System.Timers.Timer reliably is indeed a major effort. The most serious problem is that the threadpool threads that it uses to call the Elapsed event can back up due to the threadpool scheduler algorithm. Having a couple of backed-up calls isn't unusual, having hundreds is technically possible.

您需要两个同步,一个确保你只停在没有经过的事件处理程序正在运行的定时器,另以确保这些备份TP线程不会做任何伤害。像这样的:

You'll need two synchronizations, one to ensure you stop the timer only when no Elapsed event handler is running, another to ensure that these backed-up TP threads don't do any harm. Like this:

    System.Timers.Timer timer = new System.Timers.Timer();
    object locker = new object();
    ManualResetEvent timerDead = new ManualResetEvent(false);

    private void Timer_Elapsed(object sender, ElapsedEventArgs e) {
        lock (locker) {
            if (timerDead.WaitOne(0)) return;
            // etc...
        }
    }

    private void StopTimer() {
        lock (locker) {
            timerDead.Set();
            timer.Stop();
        }
    }

考虑自动复位属性设置为false。这是脆的另一种方式,所经过的事件被从捕捉异常的内部.NET方法调用。非常讨厌,你的计时器code停止,没有任何诊断运行在所有。我不知道的历史,但一定会有另一支球队在MSFT是吓和膨化这个烂摊子,并写了System.Threading.Timer。强烈推荐。

Consider setting the AutoReset property to false. That's brittle another way, the Elapsed event gets called from an internal .NET method that catches Exception. Very nasty, your timer code stops running without any diagnostic at all. I don't know the history, but there must have been another team at MSFT that huffed and puffed at this mess and wrote System.Threading.Timer. Highly recommended.

 
精彩推荐
图片推荐