服务总线 - 单例连接 Class?

Service Bus - Singleton Connection Class?

我试图弄清楚从 Web 使用服务总线的最佳实践是什么-API。

我了解到重新创建 QueueClient、SubscriptionClient 等对象是错误的方法,因此我需要重用工厂和客户端。

Service Bus client objects, such as Microsoft.ServiceBus.Messaging.QueueClient or Microsoft.ServiceBus.Messaging.MessageSender, are created through a MessagingFactory object, which also provides internal management of connections. You should not close messaging factories or queue, topic, and subscription clients after you send a message, and then re-create them when you send the next message. Closing a messaging factory deletes the connection to the Service Bus service, and a new connection is established when recreating the factory. Establishing a connection is an expensive operation that can be avoided by re-using the same factory and client objects for multiple operations.

reference

我需要实现一个特殊的 class 来保持与服务总线的连接,我正在考虑一个 Singleton class 来保持特定的操作(功能如 EnqueueJobToArchiveQueue(Job job)构造函数将初始化 "specific operation function".

将使用的 QueueClient、MessageFactory 等。

我的问题是我需要关闭对象(QueueClient.Close()),什么时候需要关闭对象?

到目前为止,这是我的 class:

 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);
    }
 }

如您所见,我没有关闭连接(QueueClient.Close()),我应该在哪里关闭连接?使用 Dispose() ?

实现 IDisposable

如果有更好的方法,请与我分享。

此代码来自具有良好工作负载的 Web-API(Azure 云服务)。

更新

我已经用 Dispose() 更新了我的 class 如下:

     public void Dispose()
     {
         if (msgFactory != null)
         {
             msgFactory.Close();
         }

     } 

服务总线 SDK 使用的默认基础协议是专有的 SBMP(服务总线消息传递协议),它在关闭工厂时关闭的 TCP/IP 连接之上工作。 如果您选择使用 TransportType=Amqp(在连接字符串中),您可以切换到 AMQP 协议。在这种情况下,工厂处理与总线的唯一 TCP 连接,并且 QueueClient、TopicClient 类(从工厂创建)在上述 TCP 连接中实例化会话和 link。 Session 和 link 是两个 AMQP 概念,用于在单个 TCP 连接上进行多路复用。 如果仅关闭 QueueClient 和 TopicClient,则关闭操作仅关闭相关会话和 link 而不会关闭关闭工厂对象时关闭的 TCP 连接。 当然我不知道 SBMP 内部是如何工作的,因为它是一个专有协议。 但是,在处置中,您可以关闭工厂和相关的 queue/topic 对象。 你有什么问题?