【问题标题】:Detect a period of no activity within a specific thread检测特定线程中没有活动的时间段
【发布时间】:2013-01-29 08:09:34
【问题描述】:

在我的 c# windows 服务中,我启动了几个线程。每个线程都应该在没有活动的特定时间段后处理它的对象。

我尝试了 System.Threading.Timer 和 System.Timers.Timer 类,但它们都在不同的线程上引发事件。

这就是发生的事情:

  • 在 service.start 期间创建多个线程
  • 每个线程监视一个目录并为每个新文件激活一个资源扩展功能
  • 在线程内 1 小时没有活动后(在此期间未处理任何文件),我想清理该线程内的资源(结构映射、线程本地类)

【问题讨论】:

  • 您尝试过任何同步方法吗?一些代码可能有用。
  • 这是一种相当不错的方式来满足您的需求:albahari.com/threading
  • 如果一个线程做了一些事情来重置计时器(它被称为重新触发吗?)。如果计时器到了,请处理它的对象。不同线程是什么意思?
  • 你是如何启动线程的?您是否希望每个线程处理对象,或者您可以取消线程。 “没有活动”在什么地方? Windows 服务?线程?如何判断是否“没有活动”?
  • 我在问题中添加了更多信息。谢谢

标签: c# multithreading


【解决方案1】:

假设“一段没有活动”你的意思是一个线程在WaitSleepJoin中的时间太长了,你可以通过调用它的Interrupt Method来中断这样一个线程:

var t = new Thread(WorkerThred);
t.Start();

// when the thread's been inactive for too long, kill it!
t.Interrupt();

这将导致在目标线程中抛出ThreadInterruptedException。因此,您可以捕获异常以释放线程的资源:

private void WorkerThred()
{
    try
    {
        DoWork();
    }
    catch (ThreadInterruptedException)
    {
        DisposeResources();
    }
}

现在您需要某种方法来跟踪每个线程保持非活动状态的时间量。例如,创建一个所有线程在进入睡眠或等待互斥体之前必须调用的方法:

public static void UpdateLastActiveTime()
{
    var t = Thread.CurrentThread;
    if (!lastActiveTime.ContainsKey(t))
        lastActiveTime.Add(t, DateTime.Now);
    else
        lastActiveTime[t] = DateTime.Now;
}

private static Dictionary<Thread, DateTime> lastActiveTime;

最后,要检查特定线程的非活动时间,请调用以下方法:

public static TimeSpan GetInactiveTime(Thread t)
{
    // if thread isn't sleeping anymore update its time
    if (t.ThreadState != ThreadState.WaitSleepJoin)
        lastActiveTime[t] = DateTime.Now;
    return DateTime.Now - lastActiveTime[t];
}

我相信使用这种模式,您将能够创建一个满足您要求的线程管理器类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多