Abort HttpWebRequest无法正常工作

时间:2013-03-14 15:55:30

标签: c# .net wpf

我正在使用此方法获取Google建议查询:

public void GetSuggestFromGoogle(string query)
    {
        try
        {
            query = HttpUtility.UrlEncode(query);
            string targetUrl = "http://suggestqueries.google.com/complete/search?ds=yt&output=toolbar&hl=en-US&q=" + query;

            UTF8Encoding utf8 = new UTF8Encoding();
            byte[] bytes = utf8.GetBytes(targetUrl);
            targetUrl = targetUrl.ToString();

            request = HttpWebRequest.Create(new Uri(targetUrl)) as HttpWebRequest;
            request.Method = "GET";

            IsDownload = true;
            request.BeginGetResponse(new AsyncCallback(FinishWebRequest), request);
        }
        catch
        {
            IsDownload = false;
            failCallback();
        }


    }

在我调用此方法之前,我使用:

public void CancelGoogleRequest()
    {
        if (IsDownload)
        {
            request.Abort();
            IsDownload = false;
        }
    }

这是完成请求方法:

private void FinishWebRequest(IAsyncResult result)
    {
        try
        {
            HttpWebResponse wResponse = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;
            Stream stream = wResponse.GetResponseStream();

            StreamReader reader = new StreamReader(stream);
            string xml = reader.ReadToEnd();

            List<string> list = this.ParseXml(xml);
            finishCallback(list);
            IsDownload = false;
        }
        catch//(Exception erere)
        {
            IsDownload = false;
            failCallback();
        }
    }

我的问题是HttpWebRequest的中止,即使我在调用新的请求之前中止FinishWebRequest方法执行,也可以取消它?

1 个答案:

答案 0 :(得分:1)

来自HttpWebRequest.Abort的备注部分:

  

Abort方法将同步执行指定的回调   如果中止,则为BeginGetRequestStream或BeginGetResponse方法   当这些操作中的任何一个未完成时调用方法。

所以你无法避免这个电话。但是你已经拥有了IsDownload标志,并且可以这样使用它:

private void FinishWebRequest(IAsyncResult result)
{
    if (IsDownload)
    {
        // handle response
    }
}

当您更改这样的取消方法时:

public void CancelGoogleRequest()
{
    if (IsDownload)
    {
        IsDownload = false; // set before Abort
        request.Abort();
    }
}

更新:如果你不能使用IsDownload标志,你可以简单地依赖以下内容(也来自备注):

  

Abort方法取消对资源的请求。请求后   取消,调用GetResponse,BeginGetResponse,EndGetResponse,   GetRequestStream,BeginGetRequestStream或EndGetRequestStream方法   导致状态属性设置为RequestCanceled

的WebException

由于您已经尝试阻止响应处理代码,所以一切都应该没问题。但是,当新请求已经启动时,您不应在异常处理程序中设置IsDownload = false,至少在WebException状态为RequestCanceled时不应如此:

private void FinishWebRequest(IAsyncResult result)
{
    try
    {
        // handle response
    }
    catch (WebException webEx)
    {
        if (webEx.Status != WebExceptionStatus.RequestCanceled)
        {
            IsDownload = false;
            failCallback();
        }
    }
    catch
    {
        IsDownload = false;
        failCallback();
    }

}

另一个想法。当Abort同步调用FinishWebRequest回调时,您可以使用IsAborted这样的标记:

public void CancelGoogleRequest()
{
    if (IsDownload)
    {
        IsDownload = false; // set before Abort
        IsAborting = true;
        request.Abort();
        IsAborting = false;
    }
}

使用这样的回调:

private void FinishWebRequest(IAsyncResult result)
{
    if (!IsAborting)
    {
        // handle response
    }
}