web-dev-qa-db-ja.com

HttpWebRequest.GetRequestStream:それは何をしますか?

コードの例:

_HttpWebRequest request =
   (HttpWebRequest)HttpWebRequest.Create("http://some.existing.url");

request.Method = "POST";
request.ContentType = "text/xml";

Byte[] documentBytes = GetDocumentBytes ();


using (Stream requestStream = request.GetRequestStream())
{
   requestStream.Write(documentBytes, 0, documentBytes.Length);
   requestStream.Flush();
   requestStream.Close();
}
_

request.GetRequestStream ()を実行すると、リクエストで送信するものがなくなります。メソッドの名前と、それが示すインテリセンス(「要求データの書き込みに使用するSystem.IO.Streamを取得する」)から、このコード行が遠隔サーバーに接続することを示すものは何もありません。
しかし、どうやら...

誰でもHttpWebRequest.GetRequestStream ()が正確に何をするのか説明できますか?

あなたの啓発をありがとう。

33
Johnny5

要求ストリームを取得しても投稿はトリガーされませんが、ストリームを閉じるとトリガーされます。投稿データは、次の方法でサーバーに送信されます。

  1. ホストへの接続が開かれます
  2. リクエストとヘッダーを送信する
  3. 投稿データの書き込み
  4. 応答を待ちます。

ストリームをフラッシュして閉じる動作は最終ステップであり、入力ストリームが閉じられると(つまり、クライアントが必要なものをサーバーに送信すると)、サーバーは応答を返すことができます。

22
mdm

GetRequestStream()を使用して、アップロードストリームへの参照を同期的に取得します。実際のリクエストが送信されるのは、ストリームへの書き込みが完了した後にのみです。

ただし、GetRequestStreamの代わりにBeginGetRequestStreamメソッドを使用することをお勧めします。 BeginGetRequestStreamは非同期に実行され、ストリームの取得中は現在のスレッドをロックしません。 BeginGetRequestStreamにコールバックとコンテキストを渡します。コールバックでは、EndGetRequestStream()を呼び出して最終的に参照を取得し、上記の書き込み手順を繰り返します(同期動作のため)。例:

context.Request.BeginGetRequestStream(new AsyncCallback(Foo), context);

public void Foo(IAsyncResult asyncResult)
    {
        Context context = (Context)asyncResult.AsyncState;
        try
        {
            HttpWebRequest request = context.Request;

            using (var requestStream = request.EndGetRequestStream(asyncResult))
            using (var writer = new StreamWriter(requestStream))
            {
                // write to the request stream
            }

            request.BeginGetResponse(new AsyncCallback(ProcessResponse), context);
        }

BeginGetRequestStreamには十分に注意してください。タイムアウトすることはないため、GetRequestStreamがタイムアウト例外をスローする状況から回復するために、プログラムにロジックを追加する必要があります。

一般に、スレッドは安価です。 HttpWebRequestの非同期のBegin/Endメソッドは、10,000以上の同時リクエストがある場合にのみ使用する価値があります。タイムアウトの実装は非常にトリッキーでエラーが発生しやすいためです。一般に、パフォーマンスを大幅に向上させる必要がない限り、BeginGetRequestStreamの使用は時期尚早な最適化です。

9
Genady Sergeev