私はこのシナリオを持っており、私の会社のすべてのワークステーションに通知メッセージを送信する必要があるところで作業しています。私たちはデスクトップ通知を処理するクライアントサービスを持っています。これは非常に簡単なWebApiです。Asynch and Parallel HttpClient 62,000台以上のマシンへのリクエスト:ベストプラクティスリクエスト
質問/要件 どうすれば両方の非同期と並行して、サーバ/ ASP.NetのWebアプリからのすべてのこれらのマシンにリクエストを送信し、カスタムログファイルへの応答をキャプチャするのですか?
通知が送信されたときに、多くのコンピュータがオフになっている可能性があります。または、マシンが廃止された可能性があるため、DNSが解決できないことがあります。
現在プロトタイプされているコードに対するリクエスト/応答サイクルは、非ブロッキングのものである必要があります。ユーザーがこれらすべてのマシンからの応答を待つ必要はありません。
宿題: 私は非同期操作を理解するにはIOバインド操作に適しています、マシンのしかし数は、私はより良い、このような状況に合うかもしれませんが、一緒に並列と非同期 感じさせるように多くのです。私はfalseに処分オプション付きのコンストラクタでServicePointManager.DefaultConnectionLimit = 10000
のHttpClientを設定している
が渡されました。以下のコード - ファクトリクラスを参照してください。
フレームワークのHttpClientクラスは再利用のために設計されていますが、基本アドレスのように一部のプロパティが変更されないことを理解しています。出典:HttpClient - This instance has already started
私は、要求/応答固有ID(相関ID)を使用して、すべての非同期操作と並列操作を特定の要求に対して同じフォルダに確実に適用します。
TaskCanceledException catchブロックがヒットすることはありません!
タイムアウトが30秒に延長されましたが、これは十分以上のものです。
プロトタイプコード:
public class HttpClientFactory : IHttpClientFactory
{
public void CreateClient(string baseUrl, Action<HttpClient> methodToExecute)
{
using (var handler = new HttpClientHandler())
{
handler.AllowAutoRedirect = true;
using (var client = new HttpClient(handler, false))
{
client.BaseAddress = new Uri(baseUrl);
client.Timeout = TimeSpan.FromSeconds(30);
methodToExecute(client);
}
}
}
}
IHttpClientFactoryが一時的である(IOC)プロトタイプコードで
workstationUrls.ForEach(baseUrl =>
{
_httpClientFactory.CreateClient(baseUrl, async (client) =>
{
await client.PostAsync(resourceUrl, content).ContinueWith(t =>
{
try
{
var response = t.Result;
var workstationResponse = new WorkstationResponse
{
StatusCode = (int)response.StatusCode,
Response = response.Content.ReadAsStringAsync().Result
};
workstationResponse.IsSuccess
= workstationResponse.StatusCode >= 200 &&
workstationResponse.StatusCode <= 299
? true
: false;
var docContent = JsonConvert.SerializeObject(workstationResponse);
if (workstationResponse.IsSuccess)
{
// Write workstation log
File.WriteAllText(path
+ "\\Bulk Notifications\\"
+ userFolder + "\\Success\\"
+ GetWorkstationNameFromUrl(baseUrl)
+ GetUniqueTimeStampForFileNames()
+ workstationResponse.IsSuccess + ".txt",
docContent);
}
else
{
// Write workstation log
File.WriteAllText(path
+ "\\Bulk Notifications\\"
+ userFolder + "\\Fail\\"
+ GetWorkstationNameFromUrl(baseUrl)
+ GetUniqueTimeStampForFileNames()
+ workstationResponse.IsSuccess + ".txt",
docContent);
}
}
catch (TaskCanceledException exe)
{
}
catch (Exception ex)
{
var workstationResponse = new WorkstationResponse
{
Exception = ex,
IsSuccess = false
};
var docContent = JsonConvert.SerializeObject(workstationResponse);
// Write workstation log
File.WriteAllText(path
+ "\\Bulk Notifications\\"
+ userFolder + "\\Fail\\"
+ GetWorkstationNameFromUrl(baseUrl) + " "
+ GetUniqueTimeStampForFileNames() + " "
+ workstationResponse.IsSuccess + ".txt", docContent);
}
});
});
});
問題: 私は例外メッセージにこれらのエラーを取得し、スタックトレースには思えません役に立った
- 「に配置されたobject.Object名にアクセスすることはできません: 『System.Net.Http.StringContent』」
- 「タスクがキャンセルされた」
アクション 'Action methodToExecute'をTaskを返すfuncに変更することから、' HttpClient'と適切に対話する非同期メソッドを待つことができます。これにより、例外が発生します。 –
Thans Peter、違いがあるかどうか試してみましょう。 – RaM