1

我有一个多线程 Windows 服务,它从 Rabbit 队列中消耗消息并根据消息的内容发送电子邮件。

当 rabbit 客户端在启动时初始化时,它使用 Min 和 Max 值限制 Threadpool 线程。

HttpClient GetAsync对于从队列中取出的每条消息,该服务使用检索电子邮件地址的方法向Web api 服务发送 HTTP 请求。

问题是请求发送到数据服务,但响应永远不会回来。Windows 服务不断消耗队列中的消息并在一段时间后挂起(可能是空闲线程的运行) - 它正在等待对 web api 的任何调用完成,而他们从未这样做过。

我能够使用SemaphoreRabbit 循环的类来解决问题,而不是尝试直接限制线程池,但是,我想知道为什么服务首先会进入这种状态。跟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);
}
4

0 回答 0