microsoft example colas c# azure azure-storage-queues

c# - example - colas azure



Pasar mensajes de objeto en Azure Queue Storage (5)

En caso de que la cola de almacenamiento se use con la función WebJob o Azure (escenario bastante común), el SDK de Azure actual permite usar el objeto POCO directamente. Vea ejemplos aquí:

Nota: El SDK utilizará automáticamente Newtonsoft.Json para la serialización / deserialización debajo del capó.

Estoy tratando de encontrar una forma de pasar objetos a la cola azul. No pude encontrar una manera de hacer esto.

Como he visto, puedo pasar cadenas o conjuntos de bytes, lo cual no es muy cómodo para pasar objetos.

¿Hay alguna forma de pasar objetos personalizados a la cola?

¡Gracias!


Esa no es la forma correcta de hacerlo. las colas no son para almacenar objetos. necesitas poner el objeto en blob o tabla (serializado). Creo que el cuerpo de cola messgae tiene un límite de tamaño de 64kb con sdk1.5 y 8kb con versiones inferiores. El cuerpo de Messgae está destinado a transferir datos crutiales para los workera que solo lo recogen.


Método de extensión que usa Newtonsoft.Json y async

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


Me gusta este enfoque de generalización, pero no me gusta tener que poner el atributo Serializar en todas las clases que me gustaría poner en un mensaje y derivarlas de una base (es posible que yo también tenga una clase base), así que utilicé ...

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<T>(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<T>(json); } } }

p.ej

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


Puede usar las siguientes clases como ejemplo:

[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<T>(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; } }

Luego, un StdQueue (una Cola fuertemente tipada):

public class StdQueue<T> 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)); } }

Entonces, todo lo que tienes que hacer es heredar BaseMessage:

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

Y haz una cola que funcione con ese mensaje:

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<ParseTaskMessage>(queue);

¡Espero que esto ayude!