如果循环花费太多时间,程序必须自动知道。 [英] Program must know automatically if a loop takes too much time.
问题描述
说我有一个for循环。如果在for循环的一个循环中花费的时间超过10分钟,我希望程序自动继续for循环。我想运行一些额外的命令来清理代码。任何想法如何实现这个?
即使循环中断我也可以管理。
FYI ,
我的问题是我的服务从SQL服务器中获取一行并在其上运行一些逻辑,但逻辑有时会进入无限循环。因此,我需要手动从SQL服务器中删除该行并重新启动该服务。
对不起英文不好
Say i have a for loop. I want the program to automatically 'continue' the for loop if the time spent inside one loop of the for loop is more than say 10 minutes. I want to run some additional commands to clean up the code too. Any Ideas how I can implement this ?
I can manage even if the loop breaks.
FYI,
My problem is that my service picks up a row from an SQL server and runs some logics on it but the logics sometimes goes into an infinite loop. Due to this I need to manually remove the row from the SQL server and restart the service.
Sorry for Bad English
推荐答案
A)
您可以尝试这种方法:
A) You could try this approach:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
class Program
{
static long counter = 0;
static void DoLongRunningTask(CancellationToken token)
{
token.ThrowIfCancellationRequested();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (true)
{
Console.Write("{0}\r",counter++);
if (token.IsCancellationRequested)
{
stopwatch.Stop();
Console.WriteLine("\nCanceled. Cleaning up. Time elapsed: {0}", stopwatch.Elapsed);
token.ThrowIfCancellationRequested();
}
}
}
static void Main()
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var task = new Task(() => DoLongRunningTask(token), token);
Console.Write("Task ");
task.Start();
tokenSource.CancelAfter(10000);
Console.Write("started and should run 10 seconds\n");
try { task.Wait(); }
catch { }
Console.WriteLine("Status: {0}", task.Status);
Console.WriteLine("IsCanceled: {0}", task.IsCanceled);
Console.WriteLine("IsCompleted: {0}", task.IsCompleted);
task.Dispose();
Console.WriteLine("Finished. Press any key.");
Console.ReadKey();
}
}
请注意,这不是蛮力取消。它不会杀死任务,它需要整洁的完成。因此,如果你被阻止在一个操作中 - 让我们在这个意义上称它为原子 - 这对你没有帮助。 (来源: http://www.blackwasp.co.uk/TaskCancellation_2.aspx [ ^ ])
但是,您不能以这种方式等待任务完成,在此期间您可以在服务中执行任何其他操作。
一篇有趣的文章,但我几分钟内无法让它工作: http://blogs.msdn.com/b/pfxteam/archive/2011/11/10/10235834.aspx [ ^ ]
B)
使用工人: http://msdn.microsoft.com/en-us/library/7a2f3ay4(v = vs.90).aspx [ ^ ]
C)
对于线程,您可以使用这种方法: http://dotnet-snippets.com/snippet/end-thread-after-timeout/656 [ ^ ],但是你要小心踩踏胎面。 (另请参阅: http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx [ ^ ]) />
无论如何,当你停止这样的执行时,你应该非常小心清理你的资源。
Please note, that this is no brute-force cancellation. It won't "kill" the task, it requires neat finishing. So if you are blocked inside one operation - let's call it atomic in this sense -, this won't help you. (Source: http://www.blackwasp.co.uk/TaskCancellation_2.aspx[^])
You can however not wait in this manner for the task to complete, you could do anything else in your service in the meantime.
An interesting article, but I couldn't get it working in a few minutes: http://blogs.msdn.com/b/pfxteam/archive/2011/11/10/10235834.aspx[^]
B)
Using workers: http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.90).aspx[^]
C)
For threading, you could use this approach: http://dotnet-snippets.com/snippet/end-thread-after-timeout/656[^], however you have top be careful with aborting treads. (see also: http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx[^])
Anyway, you should be very careful with cleaning your resources when you stop such an execution.
试试这个:
Try this:
using System.Diagnostics; // add this line to the top of your code file
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 10000; i++)
{
if (sw.Elapsed.TotalMinutes >= 10)
{
// some actions before breaking out the loop
sw.Stop();
break;
}
// other actions here
}
if (sw.IsRunning)
{
sw.Stop();
}
希望这有帮助。
Hope this helps.
这篇关于如果循环花费太多时间,程序必须自动知道。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!