RABBITMQ C#在控制台上运行良好,但不适用于服务

RABBITMQ C#在控制台上运行良好,但不适用于服务,c#,multithreading,service,rabbitmq,C#,Multithreading,Service,Rabbitmq,我通过同一网站上的或教程学习如何使用来自RabbitMQ的消息 它在控制台应用程序上运行良好! 我在做什么? 我只是使用消息并发布一个返回,这样队列中的消息就完成了,被删除了。没关系! 现在,我正在尝试使用多线程windows服务来实现这一点,因为我需要一种更好、更快的方式来使用队列中的大量消息 我发现很难找到创建服务的信息,所以我决定问您是否可以帮助我 首先,有一个奇怪的情况,我无法理解。下面让我们看看消费消息的基本结构: public static void Main() { var

我通过同一网站上的或教程学习如何使用来自RabbitMQ的消息

它在控制台应用程序上运行良好! 我在做什么? 我只是使用消息并发布一个返回,这样队列中的消息就完成了,被删除了。没关系! 现在,我正在尝试使用多线程windows服务来实现这一点,因为我需要一种更好、更快的方式来使用队列中的大量消息

我发现很难找到创建服务的信息,所以我决定问您是否可以帮助我

首先,有一个奇怪的情况,我无法理解。下面让我们看看消费消息的基本结构:

public static void Main()
{
    var factory = new ConnectionFactory() { HostName = "localhost" };
    using(var connection = factory.CreateConnection())
    using(var channel = connection.CreateModel())
    {
        channel.QueueDeclare(queue: "task_queue",durable: true,exclusive: false,autoDelete: false, arguments: null);

        channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);

        Console.WriteLine(" [*] Waiting for messages.");

        var consumer = new EventingBasicConsumer(channel);
        consumer.Received += (model, ea) =>
        {
            var body = ea.Body;
            var message = Encoding.UTF8.GetString(body);
            Console.WriteLine(" [x] Received {0}", message);

            int dots = message.Split('.').Length - 1;
            Thread.Sleep(dots * 1000);

            Console.WriteLine(" [x] Done");

            channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
        };
        channel.BasicConsume(queue: "task_queue",autoAck: false,consumer: consumer);

        Console.WriteLine(" Press [enter] to exit.");
    =>> Console.ReadLine(); <<=
    }
}
我能有别的办法吗?我做错了什么


谢谢

此代码用作windows服务。它使用TopShelf()

请阅读第二行的评论

class Program
    {
        //I declare as class fields so they are not garbage collected and the consumer can stay alive
        private EventingBasicConsumer _consumer;
        private IModel _channel;
        private IConnection _connection;

        public bool Stop()
        {
            _channel.Dispose();
            _connection.Dispose();
            return true;
        }

        public bool Start()
        {

            var factory = new ConnectionFactory() {HostName = "localhost"};
            _connection = factory.CreateConnection();
            _channel = _connection.CreateModel();

            _channel.QueueDeclare(queue: "hello",
                durable: false,
                exclusive: false,
                autoDelete: false,
                arguments: null);

            _consumer = new EventingBasicConsumer(_channel);
            _consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);

            };
            _channel.BasicConsume(queue: "hello",
                autoAck: true,
                consumer: _consumer);

            return true;
        }


        public static void Main()
        {

            var rc = HostFactory.Run(x => //1
            {
                x.Service<Program>(s => //2
                {
                    s.ConstructUsing(name => new Program()); //3
                    s.WhenStarted(tc => tc.Start()); //4
                    s.WhenStopped(tc => tc.Stop()); //5
                });
                x.RunAsLocalSystem(); //6

                x.SetDescription("Sample Topshelf Host"); //7
                x.SetDisplayName("Stuff"); //8
                x.SetServiceName("Stuff"); //9
            }); //10

            var exitCode = (int) Convert.ChangeType(rc, rc.GetTypeCode()); //11
            Environment.ExitCode = exitCode;
        }
    }
类程序
{
//我将其声明为类字段,这样它们就不会被垃圾收集,消费者就可以继续生存
私人活动基本消费者;
私人伊莫代尔频道;
专用I连接\u连接;
公共车站
{
_channel.Dispose();
_connection.Dispose();
返回true;
}
公共bool Start()
{
var factory=new ConnectionFactory(){HostName=“localhost”};
_connection=factory.CreateConnection();
_channel=_connection.CreateModel();
_channel.QueueDeclare(队列:“hello”,
持久性:错误,
独家:假,,
自动删除:false,
参数:null);
_消费者=新事件基本消费者(_渠道);
_消费者.已接收+=(型号,ea)=>
{
变量体=ea.body;
var message=Encoding.UTF8.GetString(body);
};
_channel.BasicConsume(队列:“hello”,
autoAck:是的,
消费者:_消费者);
返回true;
}
公共静态void Main()
{
var rc=HostFactory.Run(x=>//1
{
x、 服务=>//2
{
s、 ConstructUsing(name=>newprogram());//3
s、 开始时(tc=>tc.Start());//4
s、 停止时(tc=>tc.Stop());//5
});
x、 RunAsLocalSystem();//6
x、 SetDescription(“示例Topshelf主机”);//7
x、 SetDisplayName(“Stuff”);//8
x、 SetServiceName(“Stuff”);//9
}); //10
var exitCode=(int)Convert.ChangeType(rc,rc.GetTypeCode());//11
Environment.ExitCode=ExitCode;
}
}

在OnStart中创建连接/通道和一群等待传入消息的工作人员难道还不够吗。然后注册接收处理程序,该处理程序将对消息进行解码,并让工作人员对其进行处理。他们将依次处理并公布结果。OnStop应该停止通道,(可能)等待工作线程耗尽,然后处理通道/连接…我使用TopShelf()配置windows服务,RabbitMq使用者工作正常。稍后我将提供一个运行示例是的,我知道TopShelf,我以前也尝试过,但这不是重点!服务很好!主要的问题是保持从通道到控制台的连接有效。TksYes,我的代码也解决了连接保持活动的问题,它对您有效吗?我使用TopShelf只是因为我更容易测试它。我浪费了一些时间来回答你,你能告诉我你的问题现在是否解决了吗?哦,对不起,我很高兴你能帮助我。嗯……正如我所说,TopShelf没有解决我的问题,我会再试一次,我会在这里发布代码!让我们看看。。。
class Program
    {
        //I declare as class fields so they are not garbage collected and the consumer can stay alive
        private EventingBasicConsumer _consumer;
        private IModel _channel;
        private IConnection _connection;

        public bool Stop()
        {
            _channel.Dispose();
            _connection.Dispose();
            return true;
        }

        public bool Start()
        {

            var factory = new ConnectionFactory() {HostName = "localhost"};
            _connection = factory.CreateConnection();
            _channel = _connection.CreateModel();

            _channel.QueueDeclare(queue: "hello",
                durable: false,
                exclusive: false,
                autoDelete: false,
                arguments: null);

            _consumer = new EventingBasicConsumer(_channel);
            _consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);

            };
            _channel.BasicConsume(queue: "hello",
                autoAck: true,
                consumer: _consumer);

            return true;
        }


        public static void Main()
        {

            var rc = HostFactory.Run(x => //1
            {
                x.Service<Program>(s => //2
                {
                    s.ConstructUsing(name => new Program()); //3
                    s.WhenStarted(tc => tc.Start()); //4
                    s.WhenStopped(tc => tc.Stop()); //5
                });
                x.RunAsLocalSystem(); //6

                x.SetDescription("Sample Topshelf Host"); //7
                x.SetDisplayName("Stuff"); //8
                x.SetServiceName("Stuff"); //9
            }); //10

            var exitCode = (int) Convert.ChangeType(rc, rc.GetTypeCode()); //11
            Environment.ExitCode = exitCode;
        }
    }