监卸经过多次Threading.Timers [英] Monitor multiple Threading.Timers after Disposal

查看:126
本文介绍了监卸经过多次Threading.Timers的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个过程,它创建计时器(System.Threading.Timer)的动态列表,并继续运行,直到接收到信号终止。一旦接收到信号以终止我想任何现有的计时器回调来完成(见下文):

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. 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());
}

这code工作的权利,但我想监视正在执行的线程回调一旦定时器设置。我的目的是要写入日志在给定的时间间隔定时器A仍在运行。

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".

我开始玩:

ThreadPool.RegisterWaitForSingleObject(....)

附加增加了以下内容: (注:我创建了一个类ThreadContext其中包含了定时器和相关数据)

add added the following: (Note:I created a class ThreadContext which contains the timer and associated data)

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());
    }

我觉得这应该是用C#.net 4.0直线前进的任务。在我简单的单元测试,我IsRunning回调火灾相当多的等待之后。我这个电话后不进行任何进一步的执行。但我写了相当多的code,我不是太舒服,感觉像这将失败。

I feel like this should be a straight forward task in C# .net 4.0. In my simple unit test, My IsRunning callback fires quite a bit after the wait. 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?

更新 根据彼得·R·建议,我想出了下面的下面。授予其多线code,但我没有注册一个单独的线程对象。如果所有的线程处理后,仍在执行我睡了10秒,再次检查这个例子。

UPDATE Based on Peter 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. If all the threads are still executing after disposal I sleep for 10 seconds and check again for this example.

    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; }
}

_

推荐答案

如果您的处理程序还没有完成,你ManualResetEvents也不会发生。所以,你可以简单地测试,如果事件是一个信号状态或没有。即

If your handlers haven't completed, your ManualResetEvents will not be signalled. So, you could simply test if the event is in a signaled state or not. i.e.

var isComplete = waiters[0].WaitOne(0);

这篇关于监卸经过多次Threading.Timers的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆