[英]Monitor multiple Threading.Timers after Disposal
I have a process, which creates a dynamic list of timers(System.Threading.Timer) and continues to run until a signal is received to terminate.我有一个进程,它创建一个动态的计时器列表(System.Threading.Timer)并继续运行,直到收到终止信号。 Once a signal is received to terminate I want any existing timer callbacks to complete (See Below):
一旦收到终止信号,我希望任何现有的计时器回调完成(见下文):
private IList<Timer> _timers = new List<Timer>();
...
...
private void WaitOnExecutingThreads()
{
var waiters = new List<ManualResetEvent>(_timers.Count);
foreach (var timer in _timers)
{
var onWait = new ManualResetEvent(false);
waiters.Add(onWait);
timer.Dispose(onWait);
}
WaitHandle.WaitAll(waiters.ToArray());
waiters.ForEach(x=> x.Dispose());
}
This code works right now, but I would like to monitor the ongoing thread callbacks once the timers are disposed.这段代码现在可以工作,但我想在定时器被释放后监控正在进行的线程回调。 My intent is to write to a log at a given interval "Timer A is still running".
我的意图是在给定的时间间隔“定时器 A 仍在运行”写入日志。
I started playing with:我开始玩:
ThreadPool.RegisterWaitForSingleObject(....)
add added the following: (Note:I created a class ThreadContext which contains the timer and associated data)添加添加以下内容:(注意:我创建了一个包含计时器和相关数据的 class ThreadContext)
private void WaitOnExecutingThreads()
{
var waiters = new List<ManualResetEvent>();
WaitOrTimerCallback IsRunning = (x, timeout) => { if (timeout) { Log(x + "is still running"); } };
foreach (var threadContext in _threadContexts)
{
var onWait = new ManualResetEvent(false);
threadContext.Timer.Dispose(onWait);
ThreadPool.RegisterWaitForSingleObject(onWait, IsRunning , threadContext.ThreadInfo.Id, new TimeSpan(0, 0, 30), false);
waiters.Add(onWait);
}
WaitHandle.WaitAll(waiters.ToArray());
waiters.ForEach(x=> x.Dispose());
}
I feel like this should be a straight forward task in C# .net 4.0.我觉得这应该是 C# .net 4.0 中的一项直接任务。 In my simple unit test, My IsRunning callback fires quite a bit after the wait.
在我的简单单元测试中,我的 IsRunning 回调在等待后触发了相当多的时间。 I do not perform any further execution after this call.
在此调用之后,我不执行任何进一步的执行。 but I am writing quite a bit of code that I am not too comfortable with and feel like this will fail.
但是我正在编写很多我不太熟悉的代码,并且觉得这会失败。
Is there a simpler solution or I am misunderstanding something?有没有更简单的解决方案,或者我误解了什么?
UPDATE Based on Peter R.更新基于彼得 R。 suggestion I came up with the following below.
建议我想出了以下内容。 Granted its more lines of code but I don't have to register a single thread object.
授予其更多代码行,但我不必注册单线程 object。 If all the threads are still executing after disposal I sleep for 10 seconds and check again for this example.
如果处理后所有线程仍在执行,我会休眠 10 秒并再次检查此示例。
private void WaitOnExecutingThreads()
{
foreach (var threadContext in _threadContexts)
{
threadContext.DisposeWaiter = new ManualResetEvent(false);
threadContext.Timer.Dispose(threadContext.DisposeWaiter);
}
while(_threadContexts.Count > 0)
{
for(var i = 0; i < _threadContexts.Count; i++)
{
var threadContext = _threadContexts[i];
var isComplete = threadContext.DisposeWaiter.WaitOne(0);
if(isComplete)
{
Console.WriteLine(string.Format("{0}: {1} has completed", DateTime.Now, threadContext.Name));
_threadContexts.RemoveAt(i);
}
else
{
Console.WriteLine(string.Format("{0}: {1} is still running", DateTime.Now, threadContext.Name));
}
}
if (_threadContexts.Count > 0)
{
Thread.Sleep(new TimeSpan(0, 0, 10));
}
}
}
....
public class ThreadContext
{
public string Name { get; set; }
public Timer Timer { get; set; }
public WaitHandle DisposeWaiter { get; set; }
}
_ _
If your handlers haven't completed, your ManualResetEvents will not be signalled.如果您的处理程序尚未完成,您的 ManualResetEvents 将不会发出信号。 So, you could simply test if the event is in a signaled state or not.
因此,您可以简单地测试事件是否在有信号的 state 中。 ie
IE
var isComplete = waiters[0].WaitOne(0);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.