[英]How can I keep a Channel alive after an error?
I want to delete several queues on our RabbitMQ server and have some code that looks like this: 我想删除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);
}
}
}
However I get this as output: 但是我得到这个作为输出:
Queue QueueThatExists1 deleted
队列QueueThatExists1已删除
Queue QueueThatDoesn'tExist could not be deleted because Queue Not Found由于未找到队列,无法删除队列QueueThatDoesn'tExist
Queue QueueThatExists2 could not be deleted because Already Closed无法删除队列QueueThatExists2,因为已经关闭
I have changed the code to look more like this (which works as I expect): 我已经更改了代码,使其看起来更像这样(按我的预期工作):
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();
}
}
However this looks bad. 但是,这看起来很糟糕。 I have removed a
using
statement and hand rolled the same thing with a try - finally
block. 我已经删除了一条
using
语句,并try - finally
了相同的try - finally
阻止。 It feels like I am fighting the API. 感觉就像我在打API。 Question: Is there a more elegant way of achieving the same result?
问题:是否有更优雅的方法来达到相同的结果?
I notice that RabbitMQ for java has lyra and autorecovery , but cannot find anything similar for C#. 我注意到Java的RabbitMQ具有lyra和autorecovery ,但是找不到与C#类似的东西。
Check out project EasyNetQ . 签出项目EasyNetQ 。
EasyNetQ implement subscriber reconnection ( EasyNetQ doc ). EasyNetQ实现订户重新连接( EasyNetQ doc )。
Instead of a try/catch I recommend checking if that you're interested in exists. 我建议您检查一下是否存在,而不是尝试/捕获。 You can do this with the API.
您可以使用API进行此操作。 Here is our method to do that:
这是我们的方法:
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));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.