我的程序发出了Web请求,但有时我会得到一个异常,说服务器关闭了连接。发生这种情况时,我需要重新打开一个连接。
我应该把代码放在try ... catch吗?如果在try中关闭连接,请在catch中重新打开它?但我的问题是,如果服务器关闭了在catch中打开的连接怎么办?
这是我目前的代码。
public String postRequest(String pD, String url)
{
String postData = pD;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
byte[] buffer = Encoding.ASCII.GetBytes(postData);
/** Set the headers **/
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = buffer.Length;
request.ServicePoint.Expect100Continue = false;
request.Method = "post";
Stream PostData = request.GetRequestStream();
PostData.Write(buffer, 0, buffer.Length);
PostData.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader read = new StreamReader(responseStream);
String line; String source = "";
while ((line = read.ReadLine()) != null) source += line;
return source;
}
答案 0 :(得分:2)
试试Execute-Around method。 该对象采用委托,将委托作为代码块/委托完成。 object.Execute
更新:好的。 (我昨天赶紧回答)。我之前的回答假设有一种方法可以知道连接是否仍处于活动/打开状态。但是,如果我的问题推理能力是正确的,那么问题就是你不能确定conn是否存活,除非你实际使用它并接收异常。
我想了一会儿,也许我正受到我正在阅读的这本书的影响...... 我认为你需要的是相当于ruby rescue-n-retry方法
begin
# do stuff for sending a request
rescue ConnectionClosedError
# handle the error to ensure that a retry has a chance of succeeding
retry
end
现在我不认为你在C#中本地拥有它,但是可以编写足够接近的等效脚本。用goto
(屏蔽!)。这是goto简单清洁的罕见情况之一。一个例子是
static void Main()
{
for (int i = 0; i < 10; i++)
{
PostRequest();
}
}
private static void PostRequest()
{
Console.Write("Start...");
Retry:
try
{
CodeThatMightThrowAnException();
Console.WriteLine("Done!");
}
catch (ConnectionClosedException e)
{
Console.Write("Error! Attempt to reconnect...");
goto Retry;
}
}
static Random _randomizer = new Random();
private static void CodeThatMightThrowAnException()
{ var randomEvent = _randomizer.Next(20);
Console.Write("- {0} -", randomEvent);
if ( randomEvent % 3 == 0)
throw new ConnectionClosedException("Server dropped me!");
}
输出:
Start...- 10 -Done!
Start...- 16 -Done!
Start...- 9 -Error! Attempt to reconnect...- 14 -Done!
Start...- 0 -Error! Attempt to reconnect...- 3 -Error! Attempt to reconnect...-
19 -Done!
Start...- 15 -Error! Attempt to reconnect...- 6 -Error! Attempt to reconnect...-
5 -Done!
Start...- 2 -Done!
Start...- 14 -Done!
Start...- 13 -Done!
Start...- 14 -Done!
Start...- 19 -Done!
注意:当然,您需要跟踪所需的状态,并防止进入无限重试循环。
答案 1 :(得分:2)
我会循环直到达到指定的重试限制:
for(int retryCount = 0; retryCount < 5; retryCount++) {
try {
String postData = pD;
...
return source;
} catch(Exception e) {
// perhaps log exception?
}
}
正如nos已经指出的那样,你必须确保你的资源正确发布。
答案 2 :(得分:1)
让postRequest
的调用者执行try / catch并确定是否应该重试。
在postRequest内部,确保即使发生异常,也要正确清理,例如你的Streams应该包含在using()子句中。