带有rabbitMQ使用者和WebApi调用的多线程循环 - WebApi响应永远不会返回

时间:2013-06-29 12:43:09

标签: c# multithreading asp.net-web-api threadpool dotnet-httpclient

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

在启动时初始化Rabbit客户端时,它会使用最小值和最大值限制Threadpool线程。

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

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

我能够使用Semaphore类为Rabbit循环解决问题,而不是试图直接限制Threadpool,但是,我想知道为什么服务首先进入这个状态。这与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);

回调从以下行开始 - 永远不会到达空检查行:

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);
}

0 个答案:

没有答案