5

基本的な HTTP GET と POST を実行する必要がある C# 2.0 コードをいくつか書いています。System.Net.HttpWebRequest を使用して両方のタイプのリクエストを送信し、System.Net.HttpWebResponse を使用して両方を受信して​​います。GET の私のコードは次のようになります。

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format("{0}?{1}",
    URLToHit,
    queryString));
request.Method = "GET";
request.Timeout = 1000; // set 1 sec. timeout
request.ProtocolVersion = HttpVersion.Version11; // use HTTP 1.1
try
{
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
}
catch(WebException e)
{
    // If I do anything except swallow the exception here, 
    // I end up in some sort of endless loop in which the same WebException 
    // keeps being re-thrown by the GetResponse method. The exception is always 
    // right (ie: in cases when I'm not connected to a network, it gives a 
    // timed out error, etc...), but it should not be re-thrown!
}

そして、私の POST コードは非常に似ています。

URLToHit が HTTP ステータス 200 を返した場合、最後の行は正常に機能しますが、他の状況 (つまり、HTTP ステータスが 200 でない、ネットワーク接続がないなど) では、System.Net.WebException がスローされます (これは想定どおりです)。 MSDN ドキュメントに)。ただし、私のコードはその行を超えて進行することはありません。

これをデバッグしようとすると、ステップオーバーしたり、最後の行を超えて続行したりできないことがわかりました。そうしようとすると、リクエストが再発行され、例外が再スローされます。

リクエストを一度だけ発行するために私ができることについてのアイデアはありますか? 例外ベースのコードでこのようなことが起こるのを見たことがなく、アイデアがありません。私のコードの他の部分では、このようなことは何も起こらず、System.Net の機能と構造を扱う部分だけです。

ありがとう!

(更新: GetRequest メソッドに try/catch を追加)

4

5 に答える 5

1

I have the exact same problem. Here is how I produce it:

        bool shouldRetry = true;
        do {
            try
            {
                Stream newStream = myHttpWebRequest.GetRequestStream();
                newStream.Write(byteArray, 0, byteArray.Length);
                newStream.Close();
                HttpWebResponse response = (HttpWebResponse)myHttpWebRequest.GetResponse();
                shouldRetry = false;
                response.Close();
                tries++;
                status = response.StatusDescription;
            }
            catch (WebException e)
            {
                tries++;
                if (tries >= 5)
                {
                    throw e;
                }
                else
                {
                    Thread.Sleep(1000);
                }
            }
        } while (shouldRetry);

To induce the exception, I've changed my host table so the URI goes to my localhost that does not provide any proper response.

But the exception is constantly thrown! If I debug in Visual Studio, it stops at

throw e;

with an "uncaught exception" notice/box. if I press "play" to continue debugging, same row throws exception, I can not go forward in the code.

Also, it doesn't matter WHERE I throw the error. I've tried saving it and throw it after the do/while, after the function call, etc.. The exception is still thrown and is constantly there. Only way to leave is to stop debugger / exit webserver. (on localhost the process takes 100% of its CPU), when this state occur on webserver host, IIS is restarted after a while.

Aaron, did you ever solve this problem? I need that exception and I can't "swallow" it.

UPDATE: 2010-12-16

This code is in a function called send(). That function is actually called within a ThreadPool.QueueUserWorkItem like this.

            ThreadPool.QueueUserWorkItem((object state) =>
            {
                Thread.Sleep(1);
                try
                {
                    send();
                }
                catch (Exception e)
                {
                    throw e;
                }
            });

I'm currently trying to find out if that has something to do with the non-stop exceptions that eventually crash the server in my case. As I said.. It doesn't matter WHERE I catch the exception.

UPDATE: 2010-12-16 (part 2)

I do NOT get the never ending error if I avoid using ThreadPool.QueueUserWorkItem.

I'll continue to investigate.. But perhaps I could manage without ThreadPool.QueueUserWorkItem.

UPDATE: 2010-12-16 (part 3)

Thread.CurrentThread.Abort();

Instead of throwing error solves my issue

于 2010-12-15T17:43:40.033 に答える
1

別の補足として、これら 2 つのコード スニペットには違いがあります。

catch (Exception e)
{
    throw e;
}

catch (Exception e)
{
    throw;
}

最初の例では、例外のスタック トレースを現在のスタックの場所に実際にリセットします。2 番目の例では、既存のスタック トレースを保持します。コードを 2 番目の例に切り替えると、問題のデバッグに役立つ場合があります。

于 2010-12-16T13:49:20.420 に答える
1

C# には "ノンストップ" 例外はありません。例外発生時の動作を制御するには、try-catch ブロックを使用します。

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(String.Format("{0}?{1}",
    URLToHit,
    queryString));
request.Method = "GET";
request.Timeout = 1000; // set 1 sec. timeout
request.ProtocolVersion = HttpVersion.Version11; // use HTTP 1.1

try
{
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    // Code here runs if GetResponse() was successful.
}
catch (WebException ex)
{
    // Code here runs if GetResponse() failed.
}

// Code here is always run unless another exception is thrown. 

「ノンストップ例外」がない理由は、例外があると、コードが意図したとおりに実行できない可能性があるためです。たとえば、「response」変数には何が含まれていると思いますか? あなたはそれで何をしますか?try-catch ブロックを使用すると、これを完全に制御できます。

于 2009-03-16T06:15:28.547 に答える
1

これと同様の問題を見てきました。通常、例外をスローする行が再実行されるのはデバッガー自体だけですが、これは例外が最終的にキャッチされない場合にのみ発生します。

あなたは、キャッチブロックを再スローしたときにのみこの動作を示すと言います。例外を再スローしているため、その例外は最終的にどこでキャッチされて処理されますか (つまり、(再) スローで終わらないキャッチ ハンドラーによって)?

答えが「どこにもない」である場合、それが問題です。デバッガーでは、この例外スロー行の再実行が見られる可能性が高く、正常に実行された場合、アプリケーションは通常、キャッチされていない例外のためにクラッシュします。

于 2010-12-16T13:13:10.587 に答える
0

ここにいくつかの考えがあります。デバッガーはコードも実行できます。たとえば、プロパティを評価すると(ウォッチ、QuickWatchで、または値のツールチップの名前の上にマウスを置くだけでも)、デバッガーは基になるコードを実行します。そして、この間に出会うブレークポイントをヒットします。おそらくこれが原因ですか?後続の例外のコールスタックは何ですか?これはデバッガーなしでも起こりますか?

于 2010-12-16T13:24:49.720 に答える