HttpWebRequest超时问题的构建解决方法

问题描述

| 我正在使用HTTP Web Request类来调用RESTful Web服务。我需要传递数据并接收数据,而且一切似乎都很好。今天,我尝试配置该类的超时,因为运行该服务的服务器很可能处于脱机状态,并且我不想浪费时间等待。我完成了所有配置,但似乎没有什么区别。呼叫仍然等待了10秒钟以上才失败。 在调查中,我发现超时仅处理呼叫的处理,并且不包括DNS事先查询。因为这就是问题所在,所以为什么超时没有按我预期的那样工作就很有意义。 建议您进一步阅读以异步方式使用HttpWebRequest类。我已经看过这样做的代码,但不了解如何在我的代码中检索有效地同步的回调。 我的代码如下:
HttpWebRequest _serviceRequest = (HttpWebRequest)WebRequest.Create(new Uri(\"http://mywebservice.com\"));
_serviceRequest.Timeout = 3000;

HttpWebResponse response = (HttpWebResponse)_serviceRequest.GetResponse();
XmlReader reader = XmlReader.Create(response.GetResponseStream(),set);
我必须异步调用代码以以下行结束,但是我不确定应该如何获取响应对象。
IAsyncResult result = (IAsyncResult)req.BeginGetResponse(new AsyncCallback(RespCallback),reqState);
我还担心这样的半熟异步解决方案。通过同步代码使用异步方法是否是一种好习惯? 任何帮助者都感激...     

解决方法

        当调用回调函数RespCallback时,响应将可用。我不知道ѭ2拥有什么,但是我假设它包含对原始HttpWebRequest对象的引用。如果是这种情况,这将是RespCallback方法的简单实现:
void RespCallback(IAsyncResult asyncResult)
{
   ReqState reqState = (ReqState)asyncResult.AsyncState;
   HttpWebResponse resp = (HttpWebResponse)reqState.Request.EndGetResponse(asyncResult);
   // do what you need with the response.
}
更新:更多信息,如评论中所述 如果您希望使用与执行Begin调用相同的方法来响应,则可以有一个事件,该事件将在接收到回调时设置,并且可以在Begin调用之后等待该事件,如下面的示例
class ReqState {
    public HttpWebRequest Request { get; set; }
    public HttpWebResponse Response { get; set; }
    public AutoResetEvent Evt { get; set; }
}

void RespCallback(IAsyncResult asyncResult) {
    ReqState reqState = (ReqState)asyncResult.AsyncState;
    reqState.Response = (HttpWebResponse)reqState.Request.EndGetResponse(asyncResult);
    reqState.Evt.Set();
}

void CallMethod() {
    HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(...);
    // set properties on req
    ReqState state = new ReqState();
    state.Request = req;
    state.Evt = new ManualResetEvent(false);
    req.BeginGetResponse(RespCallback,state);
    state.Evt.WaitOne(TimeSpan.FromSeconds(30)); // wait for 30 seconds
    // access response via state.Response
}
现在注意,您实际上是在以异步方式进行同步调用。这使您可以更好地控制超时,但代价是代码复杂。另一件事,这在Silverlight(以及Windows Phone,IIRC)等平台上不起作用,在该平台上,同步调用(甚至那些装扮成异步的调用)也被禁止。