重试逻辑?

Raysefo

知名会员
已加入
2019年2月22日
留言内容
194
编程经验
10+
还有其他重试逻辑的方法吗?
C#:
bool redo = false;
const int maxRetries = 3;
int retries = 0;

 do
{

    try
    {

       HttpWebRequest req = (HttpWebRequest) WebRequest.Create("http://www.google.com");
       req.Timeout = 10000;

       HttpWebResponse res = (HttpWebResponse) req.GetResponse();

    }catch (TimeoutException e)
    {

       Console.WriteLine(e.Message);
       redo = true;
       ++retries;

    }
 }while (redo && retries < maxRetries) ;
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,536
地点
弗吉尼亚州切萨皮克
编程经验
10+
If you move the code into a method and follow the Single Responsibility Principle, then yes, because you can just return out of the method.
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,933
地点
英国
编程经验
10+
该代码太可怕了。如果服务器一段时间没有响应怎么办。设置一个周期性检查的计时器是否更好,从而让执行的代码有更多时间再重试?

在第17个帖子中要求mod拆分您的主题,现在对此有回复...
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,536
地点
弗吉尼亚州切萨皮克
编程经验
10+
Or instead of polling with a timer, use the actual built in asynchronous methods: HttpWebRequest.BeginGetResponse(). That should schedule an operation that will fire up a thread pool to call the callback method when the connection succeeds or fails without typing up the current running thread.
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,536
地点
弗吉尼亚州切萨皮克
编程经验
10+
在调查时,以下是伪代码中使用方法构造重试逻辑的一般模式:
C#:
bool TryDoAction(Action doSomething, int maxTries)
{
    while (maxTries-- > 0)
    {
        try
        {
            doSomething();
            return true;
        }
        catch(SomeExpectedException ex)
        {
            // log the exception and try count
        }

        // optionally put in some delay or back off heuristic here before trying again
    }
    return false;
}
确保仅捕获您期望的异常并知道如何处理。您会希望意外的异常立即冒出来。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,933
地点
英国
编程经验
10+
我没发现计时有问题 回复. As an aside, I thought this might be worth mentioning, as most devs overlook this. But, if you think you may have a dodgy connection to or from a server. You can use the using directive : using System.Net.NetworkInformation; and use the ping method in c# to check whichever server for a response. If the server(s) respond, while a request will not, you know you've got problems with your code, and not your network or server. With a few lines, you can test it like so :
C#:
            try
            {
                string domain = "csharpforums.net";
                using (Ping hitme = new Ping())
                {
                    var reply = hitme.Send(domain); bool responsive = reply.Status == IPStatus.Success; Console.WriteLine($"Response from {domain} is :: {reply.Status}");
                }
            }
            catch
            {
            }
如果在函数中运行它,请确保将PingException添加到catch中,然后将其返回false。如果您正在与其他代码(例如Web请求/响应)一起内联运行,则可以正常运行,并且可以忽略错误。在using指令中测试连接等还有一些不错的地方可以使用。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,536
地点
弗吉尼亚州切萨皮克
编程经验
10+
每种方法都有其优点和缺点:
计时器是有限的资源,无论是Windows计时器还是系统计时器。如果使用Windows计时器,则需要确保已运行消息泵,并且需要保持实际发生的协作式多任务处理的思维模式-Windows计时器不会抢占当前在UI上运行的任何其他代码线。如果使用系统计时器,则需要警惕跨线程问题。

On the other hand, using Sleep() won't cost much, except for tying up the current thread until the sleep time elapses. This would suck big time if the thread happens to be the UI thread, or an ASP.NET thread used to handle web requests.

Using async, await, coupled with Task.Delay() will free up the current thread to do other work, but introduces the overhead of the compiler generated code to make async and await to work. Again, just like with the Windows timer, there is an aspect of keeping a mental model of the cooperative-multitasking that is actually happening to prevent accidentally deadlocking yourself.
 
最佳 底部