Ron*_*Ron 5 c# azure azureservicebus azure-servicebus-queues
我试图找出从Web-API使用服务总线的最佳实践是什么。
我已经读到重新创建QueueClient,SubscriptionClient等对象是错误的方法,因此我需要重用工厂和客户端。
服务总线客户端对象(例如Microsoft.ServiceBus.Messaging.QueueClient或Microsoft.ServiceBus.Messaging.MessageSender)是通过MessagingFactory对象创建的,该对象还提供内部连接管理。发送消息后,请勿关闭消息传递工厂或将队列,主题和订阅客户端关闭,然后在发送下一条消息时重新创建它们。关闭消息传递工厂会删除与服务总线服务的连接,并且在重新创建工厂时会建立新的连接。建立连接是一项昂贵的操作,可以通过将同一工厂和客户端对象重新用于多个操作来避免。
我需要实现一个特殊的类,该类将保持与服务总线的连接,我在考虑一个Singleton类,该类将保留特定的操作(像这样EnqueueJobToArchiveQueue(Job job)的函数,构造函数将初始化QueueClient,MessageFactory等,然后由“特定的操作功能”。
我的问题是我需要关闭对象(QueueClient.Close()),什么时候需要关闭对象?
到目前为止,这是我的课程:
public class ServiceBusHelper
{
private static readonly ServiceBusHelper instance = new ServiceBusHelper();
private static MessagingFactory msgFactory;
private static NamespaceManager namespaceManager;
private const string jobQueueName = "job";
private const string responseTopicName = "jobResult";
private const string archiveQueueName = "jobArchive";
private static QueueClient archiveQueue;
private static QueueClient jobQueue;
private static TopicClient responseTopic;
private ServiceBusHelper()
{
}
static ServiceBusHelper()
{
msgFactory = MessagingFactory.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"]);
namespaceManager = NamespaceManager.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"]);
if (!namespaceManager.QueueExists(jobQueueName))
{
namespaceManager.CreateQueue(jobQueueName);
}
filteringQueue = QueueClient.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"], jobQueueName);
if (!namespaceManager.QueueExists(archiveQueueName))
{
namespaceManager.CreateQueue(archiveQueueName);
}
archiveQueue = QueueClient.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"], archiveQueueName);
if (!namespaceManager.TopicExists(responseTopicName))
{
namespaceManager.TopicExists(responseTopicName);
}
responseTopic = TopicClient.CreateFromConnectionString(ConfigurationManager.AppSettings["ServiceBusCS"],responseTopicName);
}
public static ServiceBusHelper Instance
{
get
{
return instance;
}
}
public void EnququeJobToDo(Job job, string corrId)
{
// Compose the message
BrokeredMessage msg = new BrokeredMessage(job);
msg.CorrelationId = corrId;
// Send the message
filteringQueue.Send(msg);
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我没有关闭连接(QueueClient.Close()),应该在哪里关闭连接?用Dispose()实现IDisposable?
如果有更好的方法,请与我分享。
此代码来自具有良好工作负载的Web-API(Azure云服务)。
更新资料
我用Dispose()以下方法更新了我的课程:
public void Dispose()
{
if (msgFactory != null)
{
msgFactory.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
服务总线 SDK 使用的默认底层协议是专有的 SBMP(服务总线消息传递协议),该协议在 TCP/IP 连接之上工作,关闭工厂时该连接也会关闭。如果您选择使用 TransportType=Amqp(在连接字符串中),您可以切换到 AMQP 协议。在这种情况下,工厂处理与总线的唯一 TCP 连接,并且 QueueClient、TopicClient 类(从工厂创建)实例化上述 TCP 连接内的会话和链接。会话和链接是用于在单个 TCP 连接上进行多路复用的两个 AMQP 概念。如果仅关闭QueueClient和TopicClient,则关闭操作仅关闭相关会话和链接,而不会关闭关闭工厂对象时关闭的TCP连接。当然我不知道 SBMP 内部是如何工作的,因为它是一个专有协议。但是,在处置中,您可以关闭工厂和相关的队列/主题对象。你怎么了 ?
| 归档时间: |
|
| 查看次数: |
2878 次 |
| 最近记录: |