如何为繁忙方法+ C#设置超时时间。如何设置方法的超时时间
回答
好的,这是真正的答案。
...
void LongRunningMethod(object monitorSync)
{
//do stuff
lock (monitorSync) {
Monitor.Pulse(monitorSync);
}
}
void ImpatientMethod() {
Action<object> longMethod = LongRunningMethod;
object monitorSync = new object();
bool timedOut;
lock (monitorSync) {
longMethod.BeginInvoke(monitorSync, null, null);
timedOut = !Monitor.Wait(monitorSync, TimeSpan.FromSeconds(30)); // waiting 30 secs
}
if (timedOut) {
// it timed out.
}
}
...
这结合了使用C#的两个最有趣的部分。首先,要异步调用该方法,请使用具有花式魔术裤的代表。
然后,使用监视器将消息从LongRunningMethod
发送回ImpatientMethod
,以告知消息何时完成,或者是否在一定时间内未收到消息,请放弃。
(PS-只是开玩笑这是真正的答案。我知道有2^9303的方式皮肤猫,尤其是在.NET)
你不能这样做,除非你改变方法。
有两种方式:
- 的方法是建立在其本身的尺寸了多长时间运行的时间,如果超过某个阈值,然后返回过早这种方式。
- 该方法的构建方式是监视一个变量/事件,该变量说明“何时设置此变量,请退出”,然后您有另一个线程测量第一个方法花费的时间,然后设置当经过的时间超过某个阈值时变量。
最明显的,但不幸的是,你可以在这里得到的答案是“只要在线程中运行该方法,并在运行时间过长时使用Thread.Abort”。
唯一正确的方法是让方法合作,以便在运行时间过长时进行干净的退出。
还有第三种方法,您可以在单独的线程上执行该方法,但在等待完成后需要很长时间,您只需说“我不会等待它完成,但只是丢弃它“。在这种情况下,该方法仍然会运行,并最终完成,但等待它的其他线程将简单放弃。
想想第三种方式叫某人,并要求他们在他们的房子里搜索你借给他们的那本书,等到电话结束5分钟后,你只需说出“aw,chuck it”,然后挂断。最终,其他人会找到这本书,然后回到电话上,只是注意到你不再关心结果。
方法在C#中没有超时,除非您在调试器或操作系统中认为您的应用程序已“挂起”。即使这样,处理仍然继续,只要你不杀死应用程序,就会返回响应,应用程序继续工作。
对数据库的调用可能会超时。
您可以在单独的线程中运行该方法,并对其进行监视,并在其过长时强制其退出。一种好的方法,如果你可以这样称呼它,那么将为Post Sharp中的方法开发一个属性,这样看守代码就不会乱丢你的应用程序。
我已经写了下面的示例代码(注意,示例代码的一部分,它的工作原理,但可以从多线程遭受的问题,或者如果有问题的方法捕获的ThreadAbortException会打破它):
static void ActualMethodWrapper(Action method, Action callBackMethod)
{
try
{
method.Invoke();
} catch (ThreadAbortException)
{
Console.WriteLine("Method aborted early");
} finally
{
callBackMethod.Invoke();
}
}
static void CallTimedOutMethod(Action method, Action callBackMethod, int milliseconds)
{
new Thread(new ThreadStart(() =>
{
Thread actionThread = new Thread(new ThreadStart(() =>
{
ActualMethodWrapper(method, callBackMethod);
}));
actionThread.Start();
Thread.Sleep(milliseconds);
if (actionThread.IsAlive) actionThread.Abort();
})).Start();
}
以下调用:
CallTimedOutMethod(() =>
{
Console.WriteLine("In method");
Thread.Sleep(2000);
Console.WriteLine("Method done");
},() =>
{
Console.WriteLine("In CallBackMethod");
}, 1000);
我需要在我的代码可读性上工作。
您仍然需要编写代码添加到方法做一个干净的出口时,它要完成。 – 2009-09-11 12:49:00
你的意思是像抓住ThreadAbort异常和清理资源/提供退出代码?这真的取决于所讨论的方法。 – 2009-09-11 13:06:20
如果通过“超时”,他的意思是“我想关闭我的程序,不要等待方法完成”,那么是的,可以使用Thread.Abort,但这是唯一的场景。 – 2009-09-11 13:44:01
您可以创建一个Asynchronous Method,以便您可以在“繁忙”方法完成时继续执行其他任务吗?
虽然MojoFilter's answer是很好,如果“它可能导致泄漏LongMethod“冻结。如果您对结果不再感兴趣,您应该停止操作。
public void LongMethod()
{
//do stuff
}
public void ImpatientMethod()
{
Action longMethod = LongMethod; //use Func if you need a return value
ManualResetEvent mre = new ManualResetEvent(false);
Thread actionThread = new Thread(new ThreadStart(() =>
{
var iar = longMethod.BeginInvoke(null, null);
longMethod.EndInvoke(iar); //always call endinvoke
mre.Set();
}));
actionThread.Start();
mre.WaitOne(30000); // waiting 30 secs (or less)
if (actionThread.IsAlive) actionThread.Abort();
}
我经常编写应用程序,必须跨平台同步时间关键型任务。如果你可以避免thread.abort,你应该。有关thread.abort何时适用的指导,请参阅http://blogs.msdn.com/b/ericlippert/archive/2010/02/22/should-i-specify-a-timeout.aspx和http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation。下面是我实现的概念:
- 选择性执行:只有当一个合理的成功机会存在(基于满足超时或相对于其他排队的项目成功结果的可能性的能力)上运行。如果将代码分解为段并大致了解任务块之间的预期时间,则可以预测是否应该跳过任何进一步处理。总时间可以通过用时间计算递归函数包装对象仓任务来测量,或者通过让控制器类监视工作人员知道预期的等待时间来测量。
- 选择性孤儿:如果存在合理的成功机会,请等待回报。索引的任务在受管队列中运行。超过其超时或导致其他超时风险的任务将被孤立,并返回空记录。长时间运行的任务可以包装在异步调用中。请参阅示例异步调用封装器:http://www.vbusers.com/codecsharp/codeget.asp?ThreadID=67&PostID=1
- 有条件选择:类似于选择性执行,但基于组而不是单个任务。如果许多任务互相连接,以至于一次成功或失败都会导致其他处理无关紧要,请创建一个在开始执行前检查的标志,并在长时间运行的子任务开始前再次执行检查。当你使用parallel.for或其他这样的排队并发任务时,这是特别有用的。
这是一个老问题,但它有一个更简单的解决方案,现在不可用:任务!
这里是一个示例代码:
var task = Task.Run(() => LongRunningMethod());//you can pass parameters to the method as well
if (task.Wait(TimeSpan.FromSeconds(30)))
return task.Result; //the method returns elegantly
else
throw new TimeoutException();//the method timed-out
- 1. 如何设置Socket.ConnectAsync的超时时间?
- 2. 如何设置ProxyAgent的超时时间?
- 3. 如何设置OCILogon2的超时时间?
- 4. Libtorrent如何设置超时时间?
- 5. 如何为PhantomJS设置超时时间?
- 6. 如何使用方法“CreateSqlStringAccessor”时设置“超时”?
- 7. 如何使用geo.js设置查找位置的超时时间?
- 8. 如何正确设置联合ADFS 2.0时的超时时间
- 9. 设置tweepy的超时时间
- 10. 设置查询的超时时间
- 11. 设置加载appcache的超时时间?
- 12. 设置java.net.URLConnection的最大超时时间
- 13. 为请求方法设置超时
- 14. 在Ldap搜索设置方法超时
- 15. android - 如何设置超时
- 16. 如何设置ajax超时?
- 17. 如何设置IHttpAsyncHandler超时?
- 18. CLGeocoder如何设置超时?
- 19. 如何设置NHibernate的LINQ语句的超时时间
- 20. 如何在python的套接字recv方法上设置超时?
- 21. 动态设置超时时间
- 22. 为NetworkObject.MapNetworkDrive设置超时时间
- 23. tokuDb设置时间以超时语句
- 24. iOS:Firebase存储设置超时时间
- 25. 在org.apache.commons.io.FileUtils.copyURLToFile上设置超时时间?
- 26. 设置时间会话超时
- 27. 设置会话超时时间
- 28. 在simple_html_dom中设置超时时间
- 29. ZBar iPhone,设置超时时间
- 30. 在jQuery上设置超时时间.load
这对我有用:) – 2013-09-11 10:55:37
它确实有效,但!请注意! - 当执行流程返回时,“LongRunningMethod”仍然在后台运行!这可能是泄漏。 – Alex 2013-09-29 21:34:01
这是完全正确的。如果你想停止等待一个动作,而不是停止一个动作,这是很好的。 – MojoFilter 2013-10-03 19:48:15