C#设置函数超时 [英] C# set timeout for function

查看:180
本文介绍了C#设置函数超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想运行一个函数,如果它需要超过10秒我就停止它,

我该怎么做?

谢谢

I want to run a function so that if it takes more than 10 seconds I just stop it,
How can I do it?
thanks

推荐答案

这是一个错误的想法。尽管有可能,但这种超时不应与某些功能相关联。 (并且没有函数超时这样的概念。)即使您尝试在函数级别执行此操作,也会受到极大的限制。这个函数如何调用其他函数?只有通过在递归中调用的所有函数中嵌入相同的机制?不,这样的超时只能应用于ha线程,但即使在这种情况下,这也不容易。



第一个看似明显的方法是中止线程超时调用 System.Threading.Thread.Abort 是其他一些线程。但让我们看看它有多么不安和危险。首先,如果你需要在任何合理的确定性下保证这个超时,你需要......至少两个额外的线程,而不是一个:一个线程通过调用 System.Threading.Thread来测量超时。 .Sleep 而不是调用中止,另一个线程是被中止的线程。类似的解决方案是使用计时器而不是第一个线程,这并不简单。更重要的是,由于几个原因,线程中止可能危险。通过正确处理事件可以消除一些危险 System.Threading.ThreadAbortException

http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception%28v= vs.110%29.aspx [ ^ ]。



做这样的事情需要非常了解你在做什么,也不是总是一个解决方案特别是,当您调用任何复杂对象的构造函数时允许堕胎是非常危险的。这样做可能会导致部分构造的对象,在某些情况下难以恢复的情况(如果涉及非托管资源的分配,甚至可能无法实现)。您可以通过间接堕胎调用通过间接堕胎调用开发一种临时阻止机制(甚至更复杂的机制,用于推迟),但这种机制会与您的时间要求相矛盾。



我不希望事件讨论退出线程(或函数)的其他方法,因为它们将是合作,因此与时序要求相矛盾。无论你如何做,都需要定期检查经过的时间。它不仅浪费,而且可能永远无法实现目标,因为您无法保证检查之间的所有时间段都足够短。如果你有机会调用一个本身可能需要20秒的功能,那么检查每个时间(例如0.1秒)有什么用呢?所以,这种方法是可行的,但只有在特殊情况下,才能普及。



总的来说,如果你认为这样的要求是对您的应用程序很重要,您的一般应用程序设计方向错误。如果你愿意,我们也可以讨论这个方面。



-SA
This is a wrong idea. Even though it is possible, such timeout should not be associated with certain function. (And there is no such concept as function timeout.) Even if you try to do it at the level of the function, it will be prohibitively limiting. How this function could call other functions? Only by embedding the same mechanism in all functions called, recursively? No, such timeout can be applied only to ha thread, but even in this case, this is not easy.

The first seemingly apparent method would be aborting the thread by timeout be calling System.Threading.Thread.Abort is some other thread. But let's see how uneasy and dangerous it can be. First of all, if you need to guarantee this timeout with any reasonable certainty, you would need… at least two additional thread, not one: one thread is "measuring" the timeout by calling System.Threading.Thread.Sleep and than calls Abort, and another thread is the one being aborted. And the similar solution is using a timer instead of the first thread, which is not simpler. More importantly, having a thread aborted can be dangerous, due to several reasons. Some dangers could be eliminated by proper handling of the event System.Threading.ThreadAbortException:
http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception%28v=vs.110%29.aspx[^].

Doing such thing requires very good understanding of what you are doing and is also not always a solution. In particular, it's is extremely dangerous to allow abortion when you call a constructor of any complex object. Doing so could result in a partially constructed object, the situation which, in certain situations, is hard to recover from (and may be even impossible if allocation of unmanaged resources is involved). You can develop a mechanism of temporary blocking (or even more complex mechanism, for postponing) of abortion through indirect abortion call via the use of thread synchronization in between, but this mechanism would contradict to your timing requirement.

I don't want event discuss other ways of exiting the thread (or a function), as they would be cooperative and hence contradict to the timing requirement. No matter how you do it, it would require periodic check-up of the elapsed time. Not only it could be wasteful, but you might never reach your goal, because you cannot guarantee that all time periods between the checks can be short enough. What's the use to check time every, say, 0.1 s, if you have a chance to call a function which itself could take 20 seconds? So, such approach is possible, but only to in a special situation, cannot be universal, ever.

Overall, I would say that if you feel that such requirement is important for your application, your general application design goes in a wrong direction. If you want, we can discuss this aspect, too.

—SA


有大量的如何做的例子。 选择一个...... [ ^ ]
There are plenty of examples of how to do it. Pick one...[^]


好吧,有几种方法,但它们主要取决于你如何做这个功能。



如果你只是从UI控件调用一个方法活动(例如按钮点击事件)然后几乎唯一的方法是在方法的开头保存结束时间:

Well, there are a couple of ways, but they mostly depend on how you are "doing" the function.

If you are just calling a method from a UI control activity (a button click event for example) then pretty much the only way to do it is to save the end time at the beginning of the method:
DateTime endRunAt = DateTime.Now.AddSeconds(10);



并在代码中定期检查:


And check it at intervals in your code:

foreach (MyClass mc in MyList)
    {
    //... do something to the instance
    if (DateTime.Now > endRunAt) return;
    }

如果您通过将长时间运行的任务移动到另一个线程来处理它,那么它会稍微复杂一些:您可以设置线程以支持取消(对于BackgroundWorker是WorkerSupportsCancellation属性,然后在计时器到期时从主UI调用线程上的CancelAsync。但是......不会杀死线程,线程必须检查它的CancellationPending属性并自行终止,因此主UI线程无法调用CancelAsync并假设任务已经死亡 - 直到您的代码运行为止并告知它应该自杀 - 这需要多长时间取决于您对登记进行编码的频率!

If you are handling it by moving the long-running task into a different thread, then it's slightly more complex: you can set the thread to support cancellation ( for a BackgroundWorker that is the WorkerSupportsCancellation property) and then call CancelAsync on the thread from the main UI when a timer expires. But...that doesn't kill the thread, the thread has to check it's CancellationPending property and kill itself, so the main UI thread can't call CancelAsync and assume that the task is dead - it takes until your code gets to run and notices it should be killing itself - and how long that is depends on how often you code the check in!


这篇关于C#设置函数超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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