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í:
- https://docs.microsoft.com/en-us/sandbox/functions-recipes/queue-storage
- https://github.com/Azure/azure-webjobs-sdk/wiki/Queues#trigger
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!