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

これはFinishRequestメソッドです。

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

4

1 に答える 1

2

HttpWebRequest.Abortの備考セクションから:

Abort メソッドは、BeginGetRequestStream または BeginGetResponse メソッドのいずれかが未処理のときに Abort メソッドが呼び出された場合、これらのメソッドに指定されたコールバックを同期的に実行します。

したがって、電話を避けることはできません。しかし、あなたはすでにあなたの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 メソッドを呼び出すと、Status プロパティが RequestCanceled に設定された WebException が発生します。

応答処理コードの周りに既に try ブロックがあるので、すべて問題ありません。ただしIsDownload = false、新しいリクエストがすでに開始されている場合、少なくとも WebException Status が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できます。FinishWebRequestIsAborted

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 に答える