我正在使用Azure存储队列,我想编写一些检索所有队列的代码,然后找到一个可以处理此队列中的消息的处理程序。为此,我定义了一个这样的界面:
public interface IHandler<T>
我有多个此接口的实现,例如:IHandler<CreateAccount>
或IHandler<CreateOrder>
。我为每种消息类型使用1个队列,因此CreateAccount
消息将进入create-account-queue
。
如何将它们连接起来?为了找到消息的正确Handler类,我首先需要知道消息类型,但似乎CloudQueueMessage
个对象不包含该信息。
答案 0 :(得分:2)
不是您问题的答案,但我将分享我们如何在我们的应用程序中处理完全相同的情况。
在我们的应用程序中,我们会像您一样发送不同类型的消息,并在后台进程中处理这些消息。
我们正在做的是在邮件正文中包含邮件类型。所以我们的信息通常如下:
message: {
type: 'Type Of Message',
contents: {
//Message contents
}
}
一个关键的区别是所有消息都在一个队列中(而不是在你的情况下是不同的队列)。接收方(后台进程)只轮询一个队列,获取消息并相应地识别该消息的消息类型和呼叫处理程序。
答案 1 :(得分:2)
您可以将元数据与每个队列相关联。由于您提到每个消息类型使用一个队列,因此可以将处理程序名称放在每个队列的元数据中。然后,您可以枚举所有队列并获取每个队列的元数据,以告诉您应该使用哪种类型的处理程序。这是一款快速控制台应用,可以展示我认为您所要求的内容:
using System;
using System.Collections.Generic;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Queue;
namespace QueueDemo
{
class Program
{
static void Main(string[] args)
{
//get a ref to our account.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("UseDevelopmentStorage=true;");
CloudQueueClient cloudQueueClient = storageAccount.CreateCloudQueueClient();
//create our queues and add metadata showing what type of class each queue contains.
CloudQueue queue1 = cloudQueueClient.GetQueueReference("queue1");
queue1.Metadata.Add("classtype", "classtype1");
queue1.CreateIfNotExists();
CloudQueue queue2 = cloudQueueClient.GetQueueReference("queue2");
queue2.Metadata.Add("classtype", "classtype2");
queue2.CreateIfNotExists();
//enumerate our queues in a storage account and look at their metadata...
QueueContinuationToken token = null;
List<CloudQueue> cloudQueueList = new List<CloudQueue>();
List<string> queueNames = new List<string>();
do
{
QueueResultSegment segment = cloudQueueClient.ListQueuesSegmented(token);
token = segment.ContinuationToken;
cloudQueueList.AddRange(segment.Results);
}
while (token != null);
try
{
foreach (CloudQueue cloudQ in cloudQueueList)
{
//call this, or else your metadata won't be included for the queue.
cloudQ.FetchAttributes();
Console.WriteLine("Cloud Queue name = {0}, class type = {1}", cloudQ.Name, cloudQ.Metadata["classtype"]);
queueNames.Add(cloudQ.Name);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception thrown listing queues: " + ex.Message);
throw;
}
//clean up after ourselves and delete queues.
foreach (string oneQueueName in queueNames)
{
CloudQueue cloudQueue = cloudQueueClient.GetQueueReference(oneQueueName);
cloudQueue.DeleteIfExists();
}
Console.ReadKey();
}
}
}
然而,可能更容易继承QueueMessage,然后将每个消息出列并识别您当前正在查看的子类,然后将其传递给正确的处理程序。