c# - 中止 HttpWebRequest 将不起作用

标签 c# .net wpf

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

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 方法正在执行,也可以取消它?

最佳答案

摘自HttpWebRequest.Abort中的备注部分:

The Abort method will synchronously execute the callback specified to the BeginGetRequestStream or BeginGetResponse methods if the Abort method is called while either of these operations are outstanding.

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

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

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

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

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

The Abort method cancels a request to a resource. After a request is canceled, calling the GetResponse, BeginGetResponse, EndGetResponse, GetRequestStream, BeginGetRequestStream, or EndGetRequestStream method causes a WebException with the Status property set to RequestCanceled

由于您的响应处理代码已经有一个 try block ,所以一切都应该没问题。但是,当新请求已启动时,您不应在异常处理程序中设置 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
    }
}

关于c# - 中止 HttpWebRequest 将不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15414064/

相关文章:

c# - 为什么 Count 不是无符号整数?

c# - 使用 DPAPI 对数据进行签名和验证

c# - 如何在 WPF 中为常见对话框启用视觉样式?

c# - CSLA数据库功能

c# - 获取 IEnumerable<T> 实例中类型 T 的属性名称

c# - 将 DataTable 转换为对象 [,] 的最有效方法是什么?

c# - Visual Studio 如何确定 Nullable<T> 不是结构?

c# - Resharper 警告在构造函数中使用虚函数,但与 C++ 不同,这不是错误

c# - 过滤 PropertyGrid 中显示的属性

c# - 可调整大小的网格列