在Azure队列存储中传递对象消息

我正在尝试找到一种将对象传递给Azure队列的方法。 我找不到办法做到这一点。

正如我所见,我可以传递字符串或字节数组,这对于传递对象来说并不是很舒服。

无论如何将自定义对象传递给队列?

谢谢!

您可以使用以下类作为示例:

[Serializable] public abstract class BaseMessage { public byte[] ToBinary() { BinaryFormatter bf = new BinaryFormatter(); byte[] output = null; using (MemoryStream ms = new MemoryStream()) { ms.Position = 0; bf.Serialize(ms, this); output = ms.GetBuffer(); } return output; } public static T FromMessage(CloudQueueMessage m) { byte[] buffer = m.AsBytes; T returnValue = default(T); using (MemoryStream ms = new MemoryStream(buffer)) { ms.Position = 0; BinaryFormatter bf = new BinaryFormatter(); returnValue = (T)bf.Deserialize(ms); } return returnValue; } } 

然后是StdQueue(强类型的队列):

  public class StdQueue where T : BaseMessage, new() { protected CloudQueue queue; public StdQueue(CloudQueue queue) { this.queue = queue; } public void AddMessage(T message) { CloudQueueMessage msg = new CloudQueueMessage(message.ToBinary()); queue.AddMessage(msg); } public void DeleteMessage(CloudQueueMessage msg) { queue.DeleteMessage(msg); } public CloudQueueMessage GetMessage() { return queue.GetMessage(TimeSpan.FromSeconds(120)); } } 

然后,您所要做的就是inheritanceBaseMessage:

 [Serializable] public class ParseTaskMessage : BaseMessage { public Guid TaskId { get; set; } public string BlobReferenceString { get; set; } public DateTime TimeRequested { get; set; } } 

并创建一个与该消息一起使用的队列:

 CloudStorageAccount acc; if (!CloudStorageAccount.TryParse(connectionString, out acc)) { throw new ArgumentOutOfRangeException("connectionString", "Invalid connection string was introduced!"); } CloudQueueClient clnt = acc.CreateCloudQueueClient(); CloudQueue queue = clnt.GetQueueReference(processQueue); queue.CreateIfNotExist(); this._queue = new StdQueue(queue); 

希望这可以帮助!

使用Newtonsoft.Json和async的扩展方法

  public static async Task AddMessageAsJsonAsync(this CloudQueue cloudQueue, T objectToAdd) { var messageAsJson = JsonConvert.SerializeObject(objectToAdd); var cloudQueueMessage = new CloudQueueMessage(messageAsJson); await cloudQueue.AddMessageAsync(cloudQueueMessage); } 

我喜欢这种泛化方法,但我不喜欢将Serialize属性放在我可能想要放入消息的所有类中,并从基类派生它们(我可能已经有了基类)所以我用…

 using System; using System.Text; using Microsoft.WindowsAzure.Storage.Queue; using Newtonsoft.Json; namespace Example.Queue { public static class CloudQueueMessageExtensions { public static CloudQueueMessage Serialize(Object o) { var stringBuilder = new StringBuilder(); stringBuilder.Append(o.GetType().FullName); stringBuilder.Append(':'); stringBuilder.Append(JsonConvert.SerializeObject(o)); return new CloudQueueMessage(stringBuilder.ToString()); } public static T Deserialize(this CloudQueueMessage m) { int indexOf = m.AsString.IndexOf(':'); if (indexOf <= 0) throw new Exception(string.Format("Cannot deserialize into object of type {0}", typeof (T).FullName)); string typeName = m.AsString.Substring(0, indexOf); string json = m.AsString.Substring(indexOf + 1); if (typeName != typeof (T).FullName) { throw new Exception(string.Format("Cannot deserialize object of type {0} into one of type {1}", typeName, typeof (T).FullName)); } return JsonConvert.DeserializeObject(json); } } } 

例如

 var myobject = new MyObject(); _queue.AddMessage( CloudQueueMessageExtensions.Serialize(myobject)); var myobject = _queue.GetMessage().Deserialize(); 

如果存储队列与WebJob或Azurefunction(非常常见的情况)一起使用,则当前的Azure SDK允许直接使用POCO对象。 看这里的例子:

注意:SDK将自动使用Newtonsoft.Json进行序列化/反序列化。

这不是正确的方法。 队列不是用于存储对象的。 你需要把对象放在blob或table(序列化)中。 我相信队列messgae体有64kb大小限制与sdk1.5和8kb wih较低版本。 Messgae的身体是转移为仅仅提取它的workera的重要数据。