我需要一个逻辑,当线程运行超过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.StopWatch
,System.Timers.Timer
或Threading.Timer
?
任务是检查workerThread
是否正在运行超过X时间,如果是,请调用某种方法,重置计时器并再次检查workerThread
现在是否正在运行以获取更多信息比自上次调用方法以来的X时间...依此类推...
UPD2:基本上我有一个线程根据从AmazonSQS队列中提取的信息进行处理。 SQS队列消息具有可见性超时。如果任务将花费比默认可见性超时更长的时间 - 消息将在任务完成之前返回到队列。然后它将被另一台机器拿起。为了避免这种情况,我需要扩展SQS消息的可见性超时。
所以我可以通过定期检查线程stil isALive
然后我可以添加几分钟到消息可见性超时来做到这一点。大约一分钟50秒后,我应该再次检查,如果线程仍然isALive
,那么再添加几分钟等等。
答案 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.Join
与http://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方法会阻塞,直到任务结束或发生超时。如果您不想阻止主线程,可以使用另一个并行工作的任务运行示例代码并检查工作任务。