初めまして、掲示板初めて使わせていただきます。マルチスレッドでこちらのクラスを複数回使用して動いてはいるんですが、ウェブサイトが500エラー等なんらかのエラーでリトライで再取得を試みようとするとSystem.InvalidOperationException 「要求メッセージは送信済みです。同じ要求メッセージは複数回送信できません。」で全てのスレッドのヘッダーを取得してくれなくなります。(恐らくSendAsync()で止まってる)エラーが発生した際に再度取得するようにしているつもりが、それが上手く働いてないようです。—以下コード-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; } }
おはようございます。初心者だったもので申し訳ございません。 2 こちらのサイトを一度拝見させていただきましたが、GetFileはFormsクラスの場所に配置しているのでソケットの浪費等とは関係ない可能性があります。 実装方法としてはこのようになっています。簡略化した物なので変数とかが抜けてる可能性があります。 3 申し訳遅れました。 Windows Formでの動作となります。 初期化処理で複数のスレッドを立ち上げてFormsクラスに配置されているGetFileクラスを使いまわししている感覚になります。 初めて使用した者ですが迷惑投稿者と判定されて投稿に苦戦しました。 何度投稿しても誤判定されるようなのでコードはこちらに載せます https://raw.githubusercontent.com/Misaki0331/Misaki0331.github.io/main/test/test.cs
送信済みか否かの情報は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();
- Child Tree -