【发布时间】:2017-09-05 23:54:15
【问题描述】:
我有一个带有N 消息的队列。现在我想创建一个控制台应用程序(消费者),它创建给定数量的任务/线程,每个线程将从队列中获取 1 条消息,处理它并获取一条新消息......直到队列为空。
到目前为止,这就是我所拥有的:
private static void Main(string[] args)
{
var runner = new Runner();
for (var j = 0; j < 5; j++)
{
var task = Task.Factory.StartNew(() => { runner.ReceiveMessageFromServer(); });
}
}
和
public class QRegistrator : IDisposable
{
private const string activeMqUri = "activemq:tcp://localhost:61616";
private readonly IConnection _connection;
private readonly ISession _session;
public QRegistrator(/*string activeMqUri*/)
{
var connectionFactory = new ConnectionFactory(activeMqUri);
_connection = connectionFactory.CreateConnection();
_connection.Start();
_session = _connection.CreateSession();
}
public void Dispose()
{
_connection?.Close();
}
public IMessageConsumer CreateConsumer(string queueName, string topicName)
{
//there have to be new session for each concurrent consumer
var session = _connection.CreateSession();
var queue = new ActiveMQQueue(queueName);
var consumer = string.IsNullOrWhiteSpace(topicName) ? session.CreateConsumer(queue) : session.CreateConsumer(queue, $"topic = '{topicName}'");
return consumer;
}
}
在课堂上Runner
public void ReceiveMessageFromServer()
{
var consumer = _registrator.CreateConsumer("myQueue", null);
while (true)
{
ITextMessage message = consumer.Receive() as ITextMessage;
if (message == null)
{
break;
}
Console.WriteLine("Received message with ID: " + message.NMSMessageId);
DoSomething();
}
}
但是当我运行这段代码时,有时它没有创建连接,有时它没有创建会话等。我真的不明白。当我尝试不使用 for 循环(但仍然是 task())时,它的行为相同。当我尝试没有任务时,只调用runner.ReceiveMessageFromServer() 它工作正常。谁能告诉我我做错了什么?
【问题讨论】:
-
你有多个线程共享一个
runner,运行线程安全吗?此外,在结束应用程序之前,您无需等待线程完成。 -
我认为尝试从 mq 并行出队不会提高性能(而且很可能会遇到麻烦)。我会使用单个线程将队列排入本地线程安全队列,然后并行处理本地队列中的消息。
-
@ScottChamberlain 你是对的!多么愚蠢的错误。我修复了它,但是现在,当我运行程序时,只有 1 个任务从队列接收消息,其他任务正在等待,直到这个任务完成,然后下一个任务接收消息。我必须做什么才能让它们并行运行?
-
你的问题是 prefetchPolicy
标签: c# .net task-parallel-library activemq