webrequest.begingetresponse is taking too much tim

2020-03-30 05:38发布

I am using webrequest to fetch some image data. The url may be invaild sometime. In case of invalid URL, begingetresponse is taking time equals to timeout period. Also the control become unresponsive during that period. In other word the async callback is not working asynchronously. Is this expected behaviour?

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条回答
Deceive 欺骗
2楼-- · 2020-03-30 06:10

I just ran into this same situation. While it's not a perfect workaround I decided to use the Ping.SendAsync() to ping the site first. Good part is the async part return immediately. Bad part is the extra step AND not all sites respond to Ping requests.

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
    }
}

Just code and running for a day but initial result look promising.

查看更多
在下西门庆
3楼-- · 2020-03-30 06:24

looks like this is an issue with .NET. BeginGetResponse blocks until DNS is resolved. In case of wrong URL (like http://somecrap) it tries until it gets timeout. See the following links - link1 and link2

查看更多
登录 后发表回答