C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.99207 の関連記事表示

<< 0 >>
■99207  HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ 朱里 -(2022/02/21(Mon) 00:51:06)

    分類:[C#] 

    初めまして、掲示板初めて使わせていただきます。
    マルチスレッドでこちらのクラスを複数回使用して動いてはいるんですが、ウェブサイトが500エラー等なんらかのエラーでリトライで再取得を試みようとすると
    System.InvalidOperationException 「要求メッセージは送信済みです。同じ要求メッセージは複数回送信できません。」
    で全てのスレッドのヘッダーを取得してくれなくなります。(恐らくSendAsync()で止まってる)
    エラーが発生した際に再度取得するようにしているつもりが、それが上手く働いてないようです。

    &#8212;以下コード-

    class GetFile
    {
    private string Error = ""; //エラー表示
    bool RetryFlg = false; //リトライ処理
    public GetFile()
    {
    httpClient.Timeout = TimeSpan.FromMilliseconds(3000);
    }
    HttpClient httpClient = new HttpClient();
    HttpRequestMessage headMessage;
    HttpResponseMessage response;
    int ErrorCount = 0;
    public string GetETag(string URL)//Etagの取得
    {
    try
    {
    string str= $"{URL}?{DateTime.Now.Ticks}";
    headMessage = new HttpRequestMessage(HttpMethod.Head, str);
    response = httpClient.SendAsync(headMessage).Result;
    switch (response.StatusCode)
    {
    case HttpStatusCode.OK: //取得できた時
    ErrorCount = 0;
    return response.Headers.ETag?.Tag;
    case HttpStatusCode.NotFound: //404の時
    RetryFlg = false;
    return null;
    default: //500等のサーバーエラーの時
    Error = $"ErrorCode : {response.StatusCode}";
    ErrorCount++;
    RetryFlg = true;
    return null;
    }
    }
    catch (Exception ex)
    {
    RetryFlg = true;
    Error = $"{ex.TargetSite}{ex.Message}";
    ErrorCount++;
    if (ErrorCount >= 100) //100回エラー発生でリトライ処理無効
    {
    ErrorCount = 0;
    RetryFlg = false;
    }
    Console.WriteLine($"WARN : {ex}");
    }
    return null;
    }
    }
親記事 /過去ログ172より / 関連記事表示
削除チェック/

■99208  Re[1]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ くま -(2022/02/21(Mon) 04:05:41)
記事No.99207 のレス /過去ログ172より / 関連記事表示
削除チェック/

■99209  Re[1]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ WebSurfer -(2022/02/21(Mon) 06:38:49)
    No99207 (朱里 さん) に返信

    何を作っているか (WinForms? WPF? ASP.NET Web アプリ?) と開発環境を書いてください。

    > マルチスレッドでこちらのクラスを複数回使用して

    どこがどのようにマルチスレッドなのですか?

    async/awat を使ってないのは何故ですか?
記事No.99207 のレス /過去ログ172より / 関連記事表示
削除チェック/

■99210  Re[2]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ 朱里 -(2022/02/21(Mon) 09:11:26)
    おはようございます。初心者だったもので申し訳ございません。
    
    2 こちらのサイトを一度拝見させていただきましたが、GetFileはFormsクラスの場所に配置しているのでソケットの浪費等とは関係ない可能性があります。
    実装方法としてはこのようになっています。簡略化した物なので変数とかが抜けてる可能性があります。
    
    3 申し訳遅れました。 Windows Formでの動作となります。
    初期化処理で複数のスレッドを立ち上げてFormsクラスに配置されているGetFileクラスを使いまわししている感覚になります。
    
    初めて使用した者ですが迷惑投稿者と判定されて投稿に苦戦しました。
    
    何度投稿しても誤判定されるようなのでコードはこちらに載せます
    https://raw.githubusercontent.com/Misaki0331/Misaki0331.github.io/main/test/test.cs
記事No.99207 のレス /過去ログ172より / 関連記事表示
削除チェック/

■99211  Re[3]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ WebSurfer -(2022/02/21(Mon) 09:33:57)
    No99210 (朱里 さん) に返信

    先のレスでもお願いしましたが・・・

    開発環境を書いてください。開発環境というのは OS, Visual Studio のバージョン、
    .NET Framework か Core のどっちかとそのバージョンなどの情報。

    async/awat を使ってないのは何故ですか?

    以下追加質問ですが、

    そもそもリトライは意味がないのではないですか?

    HTTP 404 応答は URL が間違っているから見つからないと Web サーバーが言っている
    のだから同じ URL で何度リトライしても意味がないはずですので。

    HTTP 500 も 5 分ぐらい待ってリトライするならともかく、短期間では何度リトライし
    ても同じ結果になると思いますので。


    > マルチスレッドでこちらのクラスを複数回使用して動いてはいるんですが、

    試しにマルチスレッドでなく単一スレッドでクラスのインスタンスは一つのみ生成して
    同じようにリトライしたらどうなりますか?


    同時接続数には制限があると思いますが、そのあたりの影響は考えていますか? HTTP 1.1
    仕様では同時接続は 2 つまでとなっています。HttpClient は試してないですが、HttpWebRequest
    を使った場合その制約が適用されるということがありました。
記事No.99207 のレス /過去ログ172より / 関連記事表示
削除チェック/

■99213  Re[4]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ 朱里 -(2022/02/21(Mon) 10:05:08)
    No99211 (WebSurfer さん) に返信
    そうでした、すみません。
    .Net Framework 4.7.2
    Visual Studio Community 2019 Version 16.11.5
    を使用しています。
    Async Awaitを使っていない理由としてはまだよく分かっていない状態なので、取り合えずThreadをnewして実行させて破棄している状態です。
    もしかしたらこちらで記しているコードに問題があるとは思いますが、404エラーは何もしない、他のエラーは自動でリトライするようにしております。
    今取得しようとしているサイト内では500エラーが起きても数秒で復活するようになっています。

    >試しにマルチスレッドでなく単一スレッドでクラスのインスタンスは一つのみ生成して
    >同じようにリトライしたらどうなりますか?
    スレッドが死ぬだけで他のスレッドは問題なかったです。
    それと同時にエラーが起きた時にGetFileをnewするとHttpClientは再初期化されるので問題は発生せず解決しました。

    >同時接続数には制限があると思いますが、そのあたりの影響は考えていますか?
    全く考えていないです。20個程度マルチスレッドで動かしていますが、問題なくヘッダーが効率的に取得できている状態です。
記事No.99207 のレス /過去ログ172より / 関連記事表示
削除チェック/

■99214  Re[5]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ WebSurfer -(2022/02/21(Mon) 10:17:53)
    No99213 (朱里 さん) に返信

    > Async Awaitを使っていない理由としてはまだよく分かっていない状態なので、取り合えずThreadをnewして実行させて破棄している状態です。

    自分にとってはすでに忘却の彼方的な Thread を使ったコードを読む気力が沸いてこないです。
    お役に立てずすみませんが他の方の回答をお待ちください。
記事No.99207 のレス /過去ログ172より / 関連記事表示
削除チェック/

■99212  Re[3]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ WebSurfer -(2022/02/21(Mon) 10:01:53)
記事No.99207 のレス /過去ログ172より / 関連記事表示
削除チェック/

■99215  Re[4]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ 朱里 -(2022/02/21(Mon) 10:22:10)
    No99214 (WebSurfer さん) に返信
    WebSurferさん、ご回答ありがとうございました。
    結果的に問題は解決しましたのでこちらのスレッドは解決済みにさせていただきます。
記事No.99207 のレス / END /過去ログ172より / 関連記事表示
削除チェック/

■99222  Re[5]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ 古谷 -(2022/02/21(Mon) 20:24:52)
    送信済みか否かの情報はHttpRequestMessageが持ってるみたいね
    
    https://github.com/microsoft/referencesource/blob/master/System/net/System/Net/Http/HttpRequestMessage.cs
    |
    | // If this field is 0 (default), then the message wasn't sent by an HttpClient instance yet. If the field
    | // value is 'messageSent', then the message was already sent and should not be sent again.
    | private int sendStatus;
    
    なので、リトライ時にHttpRequestMessageのインスタンスを再作成すればOKな感じ
    
    // NG
    var client = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get, "https://www.google.co.jp/");
    client.SendAsync(request).Wait();
    client.SendAsync(request).Wait();
    
    // OK
    var client = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get, "https://www.google.co.jp/");
    client.SendAsync(request).Wait();
    request = new HttpRequestMessage(HttpMethod.Get, "https://www.google.co.jp/");
    client.SendAsync(request).Wait();
    
記事No.99207 のレス /過去ログ172より / 関連記事表示
削除チェック/

■99223  Re[6]: HttpClient「要求メッセージは送信済みです」対処方法
□投稿者/ 古谷 -(2022/02/21(Mon) 20:25:34)
    解決済みにチェック
記事No.99207 のレス / END /過去ログ172より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -