简体   繁体   English

如何取消MassTransit中长期运行的任务

[英]How to cancel long running task in MassTransit

I am using the following example as a refernce point to create deploy MassTransit. 我将以下示例用作创建部署MassTransit的参考点。 My goal is to simulate Recovery (It works for that) Scaling (Also works) Canceling (Unable to make it work and need help around that) Continues responses/progress (progress of the job - probably my next task) 我的目标是模拟恢复(适用于此)缩放(也适用)取消(无法使其正常运行,并且需要相关帮助)继续响应/进度(工作进度-可能是我的下一项任务)

(More description as i was put on hold thanks for guiding me guys) These are the nuget packages needed (更多说明,因为我被搁置了,谢谢您的指导。)这些是所需的nuget程序包

MassTransit MassTransit.RabbitMQ RabbitMQ.Client TopShelf MassTransit MassTransit.RabbitMQ RabbitMQ.Client TopShelf

So this is the producer that i have. 这就是我的生产者。 It just takes a string to trigger a job and get the response from that job. 只需一个字符串即可触发作业并从该作业获取响应。

internal class Program
    {
        private static void Main()
        {
            IBusControl busControl = CreateBus();
            busControl.Start();
            try
            {
                for (; ; )
                {
                    Console.Write("Message to process (quit exits): ");
                    string customerId = Console.ReadLine();
                    if (customerId == "quit")
                        break;

                var serviceAddress = new Uri("rabbitmq://localhost/request_service");
                IRequestClient<ISimpleRequest, ISimpleResponse> c2 =
                    busControl.CreateRequestClient<ISimpleRequest, ISimpleResponse>(serviceAddress, TimeSpan.FromDays(10));
                Task.Run(async () =>
                {
                    ISimpleResponse response = await c2.Request(new SimpleRequest(customerId));

                    Console.WriteLine("Processing of message {0} is successful", response.CusomerName);
                });
            }
        }
        catch (Exception ex)
        {Console.WriteLine("Exception!!! OMG!!! {0}", ex);}
        finally
        {
            busControl.Stop();
        }
    }

    private static IBusControl CreateBus()
    {
        return Bus.Factory.CreateUsingRabbitMq(x => x.Host(new Uri("rabbitmq://localhost"), h =>
        {
            h.Username("guest");
            h.Password("guest");
        }));
    }
}

Below is the code for consumer. The consumer just picks up a message and have a Thread of 30 sec to simulate long running jobs.

    class Program
    {
        static int Main(string[] args)
        {
            return (int)HostFactory.Run(x => x.Service());
        }
    }

public class InitiateServiceBus : ServiceControl { IBusControl _busControl; public bool Start(HostControl hostControl) { _busControl = Bus.Factory.CreateUsingRabbitMq(x => { IRabbitMqHost host = x.Host(new Uri("rabbitmq://localhost"), h => { h.Username("guest"); h.Password("guest"); }); x.ReceiveEndpoint(host, "request_service", e => { e.Consumer<RequestConsumer>(); }); }); _busControl.Start(); return true; } public bool Stop(HostControl hostControl) { _busControl.Stop(); return true; } } public class RequestConsumer : IConsumer<ISimpleRequest> { private readonly ILog _log = Logger.Get<RequestConsumer>(); public async Task Consume(ConsumeContext<ISimpleRequest> context) { _log.InfoFormat("I am consumer {0}", context.Message.CustomerId); Thread.Sleep(TimeSpan.FromSeconds(30)); context.Respond(new SimpleResponse { CusomerName = "Processing Finished " }); } private class SimpleResponse :ISimpleResponse { public string CusomerName { get; set; } } }

And these are the messages i send public interface ISimpleRequest { DateTime Timestamp { get; } string CustomerId { get; } }

public interface ISimpleResponse { string CusomerName { get; } } public class SimpleRequest : ISimpleRequest { private readonly string _customerId; private readonly DateTime _timestamp; public SimpleRequest(string customerId) { _customerId = customerId; _timestamp = DateTime.UtcNow; } public DateTime Timestamp { get { return _timestamp; } } public string CustomerId { get { return _customerId; } } }

Any tip would be really helpful. 任何提示将非常有帮助。

I found a solution so if i use this 我找到了解决方案,所以如果我用这个

e.Consumer(() => { return reqConume; //this is a singleton }); e.Consumer(()=> {return reqConume; //这是一个单例});

and as a singleton instead of 并且作为一个单例而不是

e.Consumer(); e.Consumer();

in consumer then i have the same consumer instance and i can monitor the consumer directly. 在消费者中,那么我具有相同的消费者实例,并且我可以直接监视消费者。 Send a cancel event to it as well. 也发送取消事件。 Sorry for the trouble guys 对不起麻烦的家伙

You should use the task cancellation to achieve this. 您应该使用任务取消来实现此目的。 As per MSDN 根据MSDN

The System.Threading.Tasks.Task and System.Threading.Tasks.Task classes support cancellation through the use of cancellation tokens in the .NET Framework. System.Threading.Tasks.Task和System.Threading.Tasks.Task类通过使用.NET Framework中的取消标记来支持取消。 For more information, see Cancellation in Managed Threads. 有关更多信息,请参见托管线程中的取消。

Please check the following link for more details https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx 请检查以下链接以获取更多详细信息https://msdn.microsoft.com/zh-cn/library/dd997396(v=vs.110).aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM