Rabbit キューからメッセージを消費し、メッセージの内容に基づいて電子メールを送信するマルチスレッド Windows サービスがあります。
Rabbit クライアントが起動時に初期化されると、最小値と最大値でスレッドプール スレッドが制限されます。
キューから取り出されたメッセージごとに、サービスはメソッドを使用して Web API サービスに HTTP 要求を送信し、HttpClient
GetAsync
電子メール アドレスを取得します。
問題は、要求がデータ サービスに送られても、応答が返ってこないことです。Windows サービスはキューからメッセージを消費し続け、しばらくするとハングします (おそらくフリー スレッドが実行されます)。Web API への呼び出しが完了するのを待っていますが、決して完了しません。
スレッドプールを直接制限しようとするのではなく、Rabbit ループのクラスを使用して問題を解決できましたがSemaphore
、そもそもサービスがこの状態になった理由を知りたいです。GetAsync
通話と関係あるの?メインループが次のリクエストのためにスレッドを盗むことができるように、リクエストの期間中にスレッドを解放している可能性がありますか?
何か案は?
元のループ:
while (!_stopped)
{
if (_paused) continue;
try
{
using (var messageBusReceiver = _rabbitQueueClient.ConfigureMessageBusReceiver())
{
using (_consumer = messageBusReceiver.Listen<PublishableItem>())
{
while (!_stopped)
{
if (_paused) continue;
_consumer.Consume(callback, consumeSynchronously: false);
_communicationErrorCount = 0;
}
}
}
}
Consume
メソッドは最終的にこれを行っています:
_threadPoolProvider.QueueUserWorkItem(o =>
consumeMessage(callback, eventArgs, o), message);
コールバックは次の行で始まります。null チェック行には到達しません。
var foo = _fooService.GetFoo(messageInfo.FooId);
if (foo == null)
{
throw new FooNotFoundException(
String.Format(CultureInfo.InvariantCulture, "Foo was not found for FooId of {0}", messageInfo.FooId));
}
クライアントメソッド:
public Foo GetFoo(Guid id)
{
var path = getPathWithQueryStringAndDebug("getfoo", "id", id.ToString());
var response = _client.GetAsync(path).Result;
return processResponse<FooDto>(response);
}