确定线程运行了多长时间

时间:2012-08-28 15:46:23

标签: c# multithreading c#-4.0 timer

我需要一个逻辑,当线程运行超过X秒时,我可以做一些事情。

就像在这个令人难以置信的丑陋示例中一样,这里它会检查每一秒,如果workerThread正在运行10分钟或更长时间,它会显示一条消息......

var timeWorking = TimeSpan.FromMinutes(0);
workerThread = new Thread(RunTask);
workerThread.Start(task);
while (workerThread.IsAlive)
{
    Thread.Sleep(TimeSpan.FromSeconds(1));
    timeWorking = timeWorking.Add(TimeSpan.FromSeconds(1));
    if (timeWorking.TotalMinutes < 10) continue;
    timeWorking = TimeSpan.FromMinutes(0);
    Console.Writeline("Here we go... the event")
}

请帮我把它弄好...... 我应该使用Diagnostics.StopWatchSystem.Timers.TimerThreading.Timer

UPD:所有的答案让我更加困惑......

任务是检查workerThread是否正在运行超过X时间,如果是,请调用某种方法,重置计时器并再次检查workerThread现在是否正在运行以获取更多信息比自上次调用方法以来的X时间...依此类推...

UPD2:基本上我有一个线程根据从AmazonSQS队列中提取的信息进行处理。 SQS队列消息具有可见性超时。如果任务将花费比默认可见性超时更长的时间 - 消息将在任务完成之前返回到队列。然后它将被另一台机器拿起。为了避免这种情况,我需要扩展SQS消息的可见性超时。 所以我可以通过定期检查线程stil isALive然后我可以添加几分钟到消息可见性超时来做到这一点。大约一分钟50秒后,我应该再次检查,如果线程仍然isALive,那么再添加几分钟等等。

5 个答案:

答案 0 :(得分:2)

我认为System.Timers.Timer更适合您所描述的内容。但是,这取决于。如果您想使用计时器对UI执行某些操作。 Forms.Timer更好。

在任何一种情况下,您都可以在计时器经过(或打勾)时检查线程是否仍处于活动状态,如果是,则执行某些操作。

e.g。

    timeThreadStarted = DateTime.Now;
    workerThread = new Thread(RunTask);
    System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(1).TotalMilliseconds);
    timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    workerThread.Start(task);
//...

static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    if(workerThread != null && workerThread.IsAlive)
    {
        Console.WriteLine("thread has been running for {0}!", DateTime.Now - timeThreadStarted);
    }
}

这会在1秒后检查线程状态。如果它仍然活着,那么它已经运行了至少一秒钟。

这样做的好处是不会阻塞任何线程。如果你有一个UI并且你想要这样做,那么你就无法阻止UI线程(它将变得没有响应并且提供糟糕的用户体验)。

答案 1 :(得分:2)

由于您知道线程需要在十分钟后执行某些操作,为什么不简单地在计时器上使用这样的间隔:

var interval = 1000 * 60 * 10; // ten minutes
var timer = new System.Timers.Timer(interval) { AutoReset = false };
timer.Elapsed += ((sender, eventArgs) =>
    {
        // Do your work here...
    });

workerThread = new Thread(RunTask);
workerThread.Start(task);
timer.Start();

这样您就不会每秒检查一次,并且会在一段时间后执行您的代码。

答案 2 :(得分:1)

您也可以使用Thread.Joinhttp://msdn.microsoft.com/en-us/library/23f7b1ct.aspx上的示例TimeSpan进行Thread.Sleep,这样您就不必执行{{1}}。

注意:任何一种方法都会阻止调用线程,直到时间结束。不适合主/ UI线程。

答案 3 :(得分:0)

您可以使用定时器,该定时器会在经过时间后触发事件。

 private static void Main(string[] args)
    {
        var thread = new Thread(
            () =>
                {
                    var timer = new System.Timers.Timer
                        {
                            Interval = 10000, //10s
                            AutoReset = false, //only raise the elapsed event once
                        };
                    timer.Elapsed += timer_Elapsed;
                    timer.Start();
                    while (true)
                    {
                        Console.WriteLine("Running...");
                        Thread.Sleep(1000); //Always put a thread to sleep when its blocking so it does not waste CPU cycles.
                    }
                });
        thread.Start();
    }

    private static void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        //thread is running for more that X (10s) amount of seconds
        Console.WriteLine("Timer elapsed");
    }

这是一个简单的例子。在此示例中,线程永不退出。但是,您可以在必要时添加自己的逻辑,以获得您想要完成的任务。

简答:是的,请使用System.Timers.Timer

答案 4 :(得分:-1)

您可以使用任务等待方法,例如

var t = Task.Factory.StartNew(() => MyAction()); // MyAction is an action to be executed in parallel


bool check = t.Wait(10000); //wait for 10000 milliseconds
if (check)
{
 // all ok
}
else 
{
  // over time 
}

Wait方法会阻塞,直到任务结束或发生超时。如果您不想阻止主线程,可以使用另一个并行工作的任务运行示例代码并检查工作任务。