2

我正在使用这种方法来获取谷歌建议查询:

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();
        }
    }

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

4

1 回答 1

2

HttpWebRequest.Abort的备注部分:

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

所以你不能回避电话。但是您已经有了自己的IsDownload标志并且可以这样使用它:

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

当您像这样更改 Cancel 方法时:

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

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

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

由于您的响应处理代码周围已经有一个 try 块,所以一切都应该没问题。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
    }
}
于 2013-03-14T16:03:54.290 回答