当网址无效时,webrequest.begingetresponse会花费太多时间

时间:2009-08-05 09:30:16

标签: c# .net visual-studio

我正在使用webrequest来获取一些图像数据。网址有时可能会被拒绝。如果URL无效,则begingetresponse占用的时间等于超时时间。在此期间,控制也变得没有反应。换句话说,异步回调不是异步工作。这是预期的行为吗?

try
                                {
                                    // Async requests 
                                    WebRequest request = WebRequest.Create(uri);
                                    request.Timeout = RequestTimeOut;
                                    RequestObject requestObject = new RequestObject();
                                    requestObject.Request = request;
                                    request.BeginGetResponse(this.ProcessImage, requestObject);
                                }
                                catch (Exception)
                                {
                                    ShowErrorMessage(uri);
                                }

 private void ProcessImage(IAsyncResult asyncResult)
        {            
            try
            {
                RequestObject requestObject = (RequestObject)asyncResult.AsyncState;
                WebRequest request = requestObject.Request;
                WebResponse response = request.EndGetResponse(asyncResult);

                Bitmap tile = new Bitmap(response.GetResponseStream());
                // do something
            }
            catch (Exception)
            {
                ShowErrorMessage();
            }
        }

2 个答案:

答案 0 :(得分:2)

看起来这是.NET的一个问题。 BeginGetResponse阻止,直到解析DNS。如果URL错误(如http://somecrap),则会尝试直到超时。请参阅以下链接 - link1link2

答案 1 :(得分:1)

我刚遇到同样的情况。虽然这不是一个完美的解决方法,但我决定先使用Ping.SendAsync()来ping网站。好的部分是异步部分立即返回。不好的部分是额外的步骤,并非所有站点都响应Ping请求。

public void Start(WatchArgs args)
{
        var p = new System.Net.NetworkInformation.Ping();
        args.State = p;
        var po = new System.Net.NetworkInformation.PingOptions(10, true);
        p.PingCompleted += new PingCompletedEventHandler(PingResponseReceived);
        p.SendAsync(args.Machine.Name, 5 * 1000, Encoding.ASCII.GetBytes("watchdog"), po, args);
}

private void PingResponseReceived(object sender, .PingCompletedEventArgs e)
{
    WatchArgs args = e.UserState as WatchArgs;
    var p = args.State as System.Net.NetworkInformation.Ping;
    p.PingCompleted -= new System.Net.NetworkInformation.PingCompletedEventHandler(HttpSmokeWatcher.PingResponseReceived);
    args.State = null;
    if (System.Net.NetworkInformation.IPStatus.Success == e.Reply.Status)
    {
        //  ... BeginGetResponse now
    }
    else
    {
        /// ... machine not available
    }
}

只需编写代码并运行一天,但初步结果看起来很有希望。