简体   繁体   English

如何取消Microsoft ServiceBus MessageReceiver Receive调用?

[英]How can I cancel a Microsoft ServiceBus MessageReceiver Receive call?

I have a windows service written in .NET 4 that creates multiple threads that contain infinitely running while(running) loops. 我有一个用.NET 4编写的Windows服务,它创建了包含无限运行while(运行)循环的多个线程。 When I stop the service, the running boolean becomes false and we break out of the while loop and once each thread does that, the service finally stops. 当我停止服务时,运行的布尔值变为false,我们打破了while循环,一旦每个线程都这样做,服务终于停止。

Inside the while, it calls oMessageReceiver.Receive(TimeSpan.FromSeconds(30)). 在while内部,它调用oMessageReceiver.Receive(TimeSpan.FromSeconds(30))。 so sometimes when I try to stop the service, I have to wait up to 30 seconds for the Receive() process to timeout. 因此,有时当我尝试停止服务时,我必须等待30秒才能使Receive()进程超时。

One option would be to lower the timeout from 30 seconds to something smaller. 一种选择是将超时从30秒降低到更小。 I'm not sure of what performance penalties it'd incur, but since the process doesn't do any work without a BrokeredMessage, really I'd like to keep the listener open as often and long as possible. 我不确定它会产生什么性能损失,但是由于没有BrokeredMessage这个过程没有做任何工作,所以我真的希望尽可能经常地让听众保持开放状态。

I see that there is a .BeginReceive() method on the MessageReceiver. 我看到MessageReceiver上有一个.BeginReceive()方法。 I have a sense there would be a programming pattern I could use here that would prevent my service from hanging while I was waiting for the Receive to timeout. 我有一种感觉,我可以使用这种编程模式,在我等待接收超时的同时阻止我的服务挂起。 Can anyone describe how to use the Begin/End APM functions in an infinitely running Windows Service? 任何人都可以描述如何在无限运行的Windows服务中使用Begin / End APM功能吗?

In the new 2.1 Windows Azure SDK they have changed the Service Bus Worker Role template to use the OnMessage which recently was introduced in the 2.0 SDK. 在新的2.1 Windows Azure SDK中,他们更改了Service Bus Worker Role模板以使用最近在2.0 SDK中引入的OnMessage。 You can peek at that template to see what code it uses to get started. 您可以查看该模板以查看它用于入门的代码。 In this approach you set up an action to perform when a message arrives. 在此方法中,您可以设置要在消息到达时执行的操作。 In fact, you can also set a MaxConcurrentCalls property on the OnMessageOptions when setting it up which will handle your additional threads for you. 实际上,您还可以在设置OnMessageOptions时在OnMessageOptions上设置MaxConcurrentCalls属性,该属性将为您处理其他线程。 If you used the OnMessage approach you'd do something similar where the service would close off the QueueClient so that it wouldn't process any more. 如果您使用了OnMessage方法,那么您将执行类似的操作,该服务将关闭QueueClient,以便它不再处理。 You could also keep track with a synchronized indicator on if a message on ANY thread was processing and wait for only that processing to complete. 如果任何线程上的消息正在处理并且只等待该处理完成,您还可以使用同步指示器跟踪。

As for the best way to use the async methods (Begin/End) check out " Best Practices for Leveraging Windows Azure Service Bus Brokered Messaging " which has several examples. 至于使用异步方法(开始/结束)的最佳方法,请查看“ 利用Windows Azure Service Bus Brokered Messaging的最佳实践 ”,其中有几个示例。

Close the MessageFactory that the MessageReceiver was created from to cancel the receive operation. 关闭创建MessageReceiver的MessageFactory以取消接收操作。 I had the same issue when calling Abort or Close on the MessageReceiver before closing the message factory. 在关闭消息工厂之前,在MessageReceiver上调用Abort或Close时遇到了同样的问题。

Using the asynchronous Begin/End will make no difference. 使用异步Begin / End将没有任何区别。 As a side note if you want to run asynchronously consider creating Task wrappers using TaskFactory.FromAsync to take advantage of the new async-await features. 作为旁注,如果要异步运行,请考虑使用TaskFactory.FromAsync创建Task包装器以利用新的async-await功能。

Also see my answer on this question regarding the same issue: 另请参阅我对此问题的答案:

Cancel an Azure Service Bus QueueClient long running Receive? 取消长期运行接收的Azure Service Bus QueueClient?

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

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