C# 在发生错误后,如何使通道保持活动状态?

C# 在发生错误后,如何使通道保持活动状态?,c#,rabbitmq,C#,Rabbitmq,我想删除RabbitMQ服务器上的几个队列,并生成如下代码: string[] queuesToDelete = new[] { "QueueThatExists1", "QueueThatDoesn'tExist", // this queue causes an error - which I expect "QueueThatExists2" }; // this queue also errors - which I don't expect IConnectionF

我想删除RabbitMQ服务器上的几个队列,并生成如下代码:

string[] queuesToDelete = new[] {
  "QueueThatExists1",
  "QueueThatDoesn'tExist", // this queue causes an error - which I expect
  "QueueThatExists2" };    // this queue also errors - which I don't expect

IConnectionFactory factory = ...
using (IModel = factory.CreateModel()) {
  foreach (string queue in queuesToDelete) {
    try {
      model.QueueDelete(queue);
      Console.WriteLine("Queue {0} deleted");
    } catch (Exception e) {
      Console.WriteLine("Queue {0} could not be deleted because {1}", queue, e);
    }
  }
}
但是,我将其作为输出:

已删除存在的队列1
由于找不到队列,因此无法删除队列未列出的队列
无法删除现有队列2,因为队列已关闭

我已经更改了代码,使其看起来更像这样(正如我所期望的那样):

然而,这看起来很糟糕。我使用语句删除了一个
,并用一个
try-finally
块手动滚动了相同的内容。感觉就像我在和API做斗争问题:有没有更优雅的方法达到同样的效果

我注意到RabbitMQ for java有和,但找不到与C#类似的东西。

签出项目


EasyNetQ实现订户重新连接()。

我建议您检查是否存在您感兴趣的订阅服务器,而不是try/catch。您可以通过API实现这一点。以下是我们的方法:

  private bool DoesSomethingExist(string something, string queueOrExchange)
    {
        var connectionInfo = GetRabbitConnectionInfo();
        var url = string.Format("{0}/{1}/{2}/{3}", connectionInfo.APIUrl, queueOrExchange, connectionInfo.VirtualHostName, something);
        using (var client = new HttpClient())
        {
            var byteArray = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", connectionInfo.UserName, connectionInfo.Password));
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
            var response = client.GetAsync(url).Result;
            if (response.StatusCode == HttpStatusCode.OK)
            {
                return true;
            }
            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                return false;
            }

            var content = response.Content;
            throw new Exception(string.Format("Unhandled API response code of {0}, content: {1}", response.StatusCode, content));
        }
    }

JFYI:存在关闭通道的通道级错误和强制关闭连接内部所有通道以及连接本身的连接级错误。在发生此类错误后,您的频道无法生存。当然,有一些常规错误不会导致通道或连接关闭。但这也取决于客户端库的实现。好主意,我的批评是,我还必须添加一个
IsQueueLocked()
,以检查队列在删除之前是否未锁定,以及
DoIHaveDeletingPermissions()
,并且。。。再加上未来发生的一切。
  private bool DoesSomethingExist(string something, string queueOrExchange)
    {
        var connectionInfo = GetRabbitConnectionInfo();
        var url = string.Format("{0}/{1}/{2}/{3}", connectionInfo.APIUrl, queueOrExchange, connectionInfo.VirtualHostName, something);
        using (var client = new HttpClient())
        {
            var byteArray = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", connectionInfo.UserName, connectionInfo.Password));
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
            var response = client.GetAsync(url).Result;
            if (response.StatusCode == HttpStatusCode.OK)
            {
                return true;
            }
            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                return false;
            }

            var content = response.Content;
            throw new Exception(string.Format("Unhandled API response code of {0}, content: {1}", response.StatusCode, content));
        }
    }