none
HttpClientの使い方について RRS feed

  • 質問

  • VS2017を使用しています。

    他の人が作ったプログラムを修正して欲しいと依頼されたのですが、
    そのコードの中のHttpClientの使い方が「こんなことが可能なのか」
    と感じまして質問させていただきます。

    仕様:
    複数端末に対して制御を行うプログラムです。
    サーバが受信した電文を、各端末ごとの固有の電文に変換して送信します。

    処理の流れ:
    HttpClientはグローバルでstaticで宣言しており、送り先端末ごとに1つ生成しています。

    サーバは電文を受け取る都度、端末に送信するクラスを"new"しています。
    全て非同期で処理されており、場合によっては前の処理中に次の処理が来ます。
    一つのHttpClientで同時に通信が行えるものなのでしょうか?
    また、このような使い方は正しいのでしょうか?

    もう1点、別件で作成したテスト用のアプリです。
    HttpClientを使って10秒間隔でクライアントに要求を出し続けた場合、1日半程度
    でOSのメモリーが不足してしまうのですが、回避策はありますでしょうか。
    接続先は一つでHttpClientはClose/Disposeともに行っていません。

    2018年11月20日 2:10

回答

すべての返信

  • > 他の人が作ったプログラムを修正して欲しいと依頼されたのですが、

    作った人に聞くべき話ですが、聞けない事情があるのですか?

    ここに書いてあること以外は知り得ない第三者には作った人がどのように考えて実装したか等は分からないので、作った人の意図まで含めた的を得た回答をするのは無理だと思うのですが。

    ・・・と言うばかりでは何なので、レスできるところだけレスします。

    > 一つのHttpClientで同時に通信が行えるものなのでしょうか?

    一つではなくて、

    > HttpClientはグローバルでstaticで宣言しており、送り先端末ごとに1つ生成しています。

    ではないのですか? であれば、「送り先端末ごと」に別スレッドを使って非同期に通信できます。同時ではないですが。

    > また、このような使い方は正しいのでしょうか?

    正しいかどうかまではアプリの全体が分からないと分かりませんが、そういう実装は普通だと思います。特に UI をブロックしないという必要があれば必須ではないかと思います。


    > もう1点、別件で作成したテスト用のアプリです。
    > HttpClientを使って10秒間隔でクライアントに要求を出し続けた場合、1日半程度
    > でOSのメモリーが不足してしまうのですが、回避策はありますでしょうか。

    そこは分かりませんが、

    > 接続先は一つでHttpClientはClose/Disposeともに行っていません。

    とするのは、HttpClient の初期化と Dispose を繰り返すようなことをすると、socket が浪費されるという問題があるそうですので、そういうことにならざるを得ないかと。

    詳しくは以下の記事を見てください。

    You're using HttpClient wrong and it is destabilizing your software
    https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

    > HttpClientはグローバルでstaticで宣言しており、

    というのは、たぶんそれが理由ではないかと想像しています。



    • 編集済み SurferOnWww 2018年11月20日 2:51 誤字訂正
    2018年11月20日 2:48
  • ご回答ありがとうございます。

    書き方が悪かったようです。

    問題視しているのは同じ端末に対して幾つも平行送信するケースです。

    別件のソケット枯渇の件ですが、
    ご指摘の内容が掴めないでおります

    >> 接続先は一つでHttpClientはClose/Disposeともに行っていません。

    >とするのは、HttpClient の初期化と Dispose を繰り返すようなことをすると、socket が浪費されるという問題があるそうですので、そういうことにならざるを得ないかと。

    Close/Disposeともに行っていませんのでsokectを浪費していないと認識しております。
    HttpClientのnewはロード時の一回です。この件はローカルのStaticで使用しています。(仮にグローバル(public)にしたとしても同じ動きかと思うのですが。

    2018年11月20日 3:31
  • > 問題視しているのは同じ端末に対して幾つも平行送信するケースです。

    そこは作った人に聞いていただければと思います。

    作った人がそうする必要があると判断してそうしたのかもしれません。ここに書いてあること以外は知り得ない第三者にはそのあたりの事情は分かりませんので、それが正しいかどうかの話はできないと思います。

    > 別件のソケット枯渇の件ですが、
    > ご指摘の内容が掴めないでおります

    言葉足らずで誤解されたようで、すみません。質問者さんが書いた、

    > 接続先は一つでHttpClientはClose/Disposeともに行っていません。

    ・・・というのは socket 枯渇の問題を避けるために正しいと言っただけです。

    メモリ不足になる原因は全く分かりませんので、socket 枯渇とメモリ不足の話は私の頭の中ではつながってません。
    2018年11月20日 4:12
  • 確認したいのは

    一つのHttpClientソケットで同時に複数の送信処理を行えるのか、ということです。

    現在のつくりでは送信中に、次の送信を行う可能性があります。

    作り手が動きをよく理解しないままに作成しているので、不具合が出てこちらに修正依頼が来ており、使えるコードは残すつもりで調べいたら、という状況です。

    宜しくお願い致します。


    2018年11月20日 4:29
  • 一つのHttpClientで同時に通信が行えるものなのでしょうか?

    また、このような使い方は正しいのでしょうか?

    以下の記事が詳しいと思います。

    HttpClientをマルチスレッドで運用する場合の注意点
    https://qiita.com/skitoy4321/items/dc6bd2b62b62c2414642


    もう1点、別件で作成したテスト用のアプリです。
    HttpClientを使って10秒間隔でクライアントに要求を出し続けた場合、1日半程度
    でOSのメモリーが不足してしまうのですが、回避策はありますでしょうか。
    接続先は一つでHttpClientはClose/Disposeともに行っていません。

    まずは調査しなければ対策が立てられません。.NET C# メモリーリーク辺りで検索すると調査方法が見つかると思います。例えば、以下です。

    メモリリーク検出ツールについて
    https://social.msdn.microsoft.com/Forums/ja-JP/5a0f5abe-aebc-4d4d-a681-b53c26e44547/12513125141252212522125401246326908209861248412540125231239512?forum=wpfja


    ★良い回答には質問者は回答済みマークを、閲覧者は投票を!

    • 回答としてマーク yokohamaUser 2018年11月20日 5:09
    2018年11月20日 5:02
    モデレータ
  • ありがとうございます。参考になります。

    メモリーリーク、調査が必要ですか・・・了解です。

    他の方も検証で同じような使い方をされて、同じ現象がでていないかな、と思ったのですが。

    Sockを使っても同じ現象が出たので、今回は頑張って調べてみます。ありがとうございました。

    2018年11月20日 5:14
  • 一番最初の質問に書いてあった通り、

    > HttpClientはグローバルでstaticで宣言しており、送り先端末ごとに1つ生成しています。

    ・・・ということには変わりなく、

    > 確認したいのは
    > 一つのHttpClientソケットで同時に複数の送信処理を行えるのか、ということです。
    > 現在のつくりでは送信中に、次の送信を行う可能性があります。

    ・・・というのは、ある一つの「送り先」に対し一つの HttpClient インスタンスを使いまわすということですよね。

    であれば、「同時に複数の送信処理」はできるはずがないと思いますけど。

    「作った人」は、同時要求をキューに入れて順次実行するというような手段を取っていて、要求が多くなりすぎキューからあふれて不具合が生じているというような話なんですかね?

    どのように実装していて、どのような不具合が出たのか書いてないので実際のところは分かりませんが・・・
    • 編集済み SurferOnWww 2018年11月20日 6:42 訂正
    2018年11月20日 6:05