在 C# 中重复一个函数,直到它不再抛出异常
我有一个调用 SOAP 接口并返回数据数组的类。但是,如果此请求超时,则会引发异常。这很好。但是,我希望我的程序尝试再次进行此调用。如果超时,我希望它继续拨打此电话,直到成功为止。我怎样才能做到这一点?
例如:
try
{
salesOrdersArray = MagServ.salesOrderList(sessID, filter);
}
catch
{
?? What Goes Here to FORCE the above line of code to rerun until it succeeds.
}
I've got a class that calls a SOAP interface, and gets an array of data back. However, if this request times out, it throws an exception. This is good. However, I want my program to attempt to make this call again. If it times out, I'd like it to keep making this call until it succeeds. How can I accomplish this?
For example:
try
{
salesOrdersArray = MagServ.salesOrderList(sessID, filter);
}
catch
{
?? What Goes Here to FORCE the above line of code to rerun until it succeeds.
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
您只需要永远循环:
请注意,几乎可以肯定您不应该永远循环。几乎可以肯定,您应该有最大尝试次数,并且可能只捕获特定异常。永远捕获所有异常可能会令人震惊......想象一下,如果
salesOrderList
(非常规方法名称,顺便说一句)抛出ArgumentNullException
因为您遇到了错误并且filter
为空...您真的想要永远占用 100% 的 CPU 吗?You just need to loop forever:
Note that you should almost certainly not actually loop forever. You should almost certainly have a maximum number of attempts, and probably only catch specific exceptions. Catching all exceptions forever could be appalling... imagine if
salesOrderList
(unconventional method name, btw) throwsArgumentNullException
because you've got a bug andfilter
is null... do you really want to tie up 100% of your CPU forever?您必须将 try/catch 块放置在循环构造内。如果您不希望消耗 100% 的处理器,请在 catch 块中放置 Thread.Sleep,这样每次发生异常时,它都会等待一段时间,从而释放处理器以执行其他操作。
您还可以指定异常类型,以便仅处理超时异常,并传递其他类型的异常。
请注意,TimeOutException 应该替换为异常的真实名称...我不知道这是否是真实名称。
还要调整睡眠时间(以毫秒为单位)和重复次数,在我介绍的情况下,100 次 1000 毫秒的重复会产生 1 分 40 秒的最大等待时间,加上操作时间本身。
You must place the try/catch block inside a loop construct. If you wish not to consume 100% of your processor place a Thread.Sleep in the catch block, so everytime an exception occurs, it will wait some time, freeing the processor to do other things.
You could also specify exception type, so that only the timeout exception is handled, and other kinds of exceptions pass-through.
Note that, TimeOutException should be replaced by the real name of the exception... I don't know if that is the real name.
Also adjust the sleep time, given in millisecs and the amount of repeats, in the case I presented, 100 repeats of 1000ms yields a maximum wait of 1 minute and 40 seconds, plus the operation time itself.
如果您无法更改超时,则以下内容应该有效。 salesOrdersArray 应初始化为
null
。If you can't change the timeout, the below should work. salesOrdersArray should be initialized to
null
.使用异常作为控制流通常不是一个好主意,但这将满足您的要求。
It its not gernally a good idead to use exceptions as control flow, but this will do what you requested.
我将使用事务性队列 (MSMQ) 来存储服务调用。循环将使消息出队并调用 TransactionScope 中的服务,如果调用失败,则消息看起来仍在队列中。可以通过在消息中添加到期时间来指定总体超时。如果您确实想要一个可靠的解决方案,那么这个解决方案很好,因为我猜调用该操作至关重要。
I will use a transactional queue (MSMQ) to store the service call. A loop will dequeue messages and call the service in a TransactionScope, if the call fails the message appear to be still in the queue. An ov erall timeout can be specified by adding a time to expire in the message. This solution is good if you really want a reliable solution since I guessed that calling that operation is critical.
尝试
如果这永远不会成功,您所追求的行为可能会导致无限循环......
Try
The behavior you are after might cause an endless loop if this never succeeds though...
尝试这样的事情:
编辑:哇!伟大的思想都是相似的! :)
Try something like this:
Edit: Wow! Great minds think alike! :)
尽管我不建议您无限次地执行此操作,但您可以从这句话中创建一个单独的函数:
Although I would NOT recommend you to do this for an infinite number of times, you could make a separate function out of that one sentence:
这将永远运行,并且使用异常作为循环,速度很慢。有没有一种方法可以修改函数使其返回 null,而不是抛出异常?如果您预计此调用会定期失败,请不要使用 try/catch 块。
This will run forever, and is using exceptions as a loop which is slow. Is there a way you can modify your function that it returns null, instead of throwing an exception? If you're expecting that this call will fail regularly, don't use a try/catch block.
我遵循这种模式来解决这个问题:
永远尝试似乎不是一个好主意,因为你最终可能会遇到无限的过程。如果您认为需要多次尝试才能实现目标,请在此处设置大量数字。
我个人认为明智的做法是在每次尝试 Thread.Sleep(1000); 之后再调用 Send(data); 等待几毫秒或几秒——例如,您可以,如果您认为适合您的场景,请使用 attempNumber 变量来增加或减少此等待时间。
I follow this pattern in order to solve this problem:
Trying forever seems not to be a good idea as you may end up having an infinite process. If you think you need many attempts to achieve your goal just set huge number here.
I personally think its wise to wait some milliseconds, or seconds after eac attempt Thread.Sleep(1000); before callig Send(data); --- you could for example, use the attempNumber variable to increse or decrease this waiting time if you think its wise for your scenario.