webentwicklung-frage-antwort-db.com.de

Übergeben von Objektnachrichten an den Azure-Warteschlangenspeicher

Ich versuche, einen Weg zu finden, Objekte an die Azure-Warteschlange zu übergeben. Ich konnte keinen Weg finden, dies zu tun.

Wie ich gesehen habe, kann ich ein String- oder Byte-Array übergeben, was für das Übergeben von Objekten nicht sehr angenehm ist.

Gibt es überhaupt benutzerdefinierte Objekte an die Warteschlange zu übergeben?

Vielen Dank!

25
Roman

Sie können die folgenden Klassen als Beispiel verwenden:

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

Dann eine StdQueue (eine stark typisierte Warteschlange):

   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));
        }
    }

Dann müssen Sie nur noch die BaseMessage erben:

[Serializable]
public class ParseTaskMessage : BaseMessage
{
    public Guid TaskId { get; set; }

    public string BlobReferenceString { get; set; }

    public DateTime TimeRequested { get; set; }
}

Und mach eine Warteschlange, die mit dieser Nachricht funktioniert:

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);

Hoffe das hilft!

30
astaykov

Erweiterungsmethode, die Newtonsoft.Json und Async verwendet

    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);
    }
15
Akodo_Shado

Ich mag diesen Verallgemeinerungsansatz, aber ich mag es nicht, das Serialize-Attribut allen Klassen zuordnen zu müssen, die ich möglicherweise in eine Nachricht einfügen möchte, und diese von einer Basis abzuleiten (möglicherweise habe ich auch bereits eine Basisklasse).

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);
        }
    }
}

z.B.

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

var myobject = _queue.GetMessage().Deserialize<MyObject>();
9
acro

Wenn die Speicherwarteschlange mit der WebJob- oder Azure-Funktion verwendet wird (recht allgemeines Szenario), können Sie mit dem aktuellen Azure-SDK das POCO-Objekt direkt verwenden. Beispiele hier sehen:

Hinweis: Das SDK verwendet Newtonsoft.Json automatisch für die Serialisierung/Deserialisierung unter der Haube.

0
Toma Bussarov