如何在出错后保持频道有效?

时间:2015-02-26 12:27:12

标签: 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

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

但是我把它作为输出:

  

Queue QueueThatExists1已删除
  由于未找到队列,因此无法删除队列队列,因此无法删除   Queue QueueThatExists2因为已经关闭而无法删除

我已将代码更改为更像这样(按预期工作):

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 = ...
IModel model;
try {
  model = 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);
      // reset the connection
      model.Dispose();
      model = factory.CreateModel();
    }
  } finally {
    if (model != null)
      model.Dispose();
  }
}

然而这看起来很糟糕。我删除了using语句,并使用try - finally块手动滚动相同的内容。感觉就像我在争夺API。 问题:是否有更优雅的方式来实现相同的结果?

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

2 个答案:

答案 0 :(得分:1)

查看项目EasyNetQ

EasyNetQ实现用户重新连接(EasyNetQ doc)。

答案 1 :(得分:1)

我建议检查您感兴趣的是否存在,而不是尝试/捕获。您可以使用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));
        }
    }