简体   繁体   English

Azure服务总线队列-当消息在队列中时,QueueClient.Receive()返回空的BrokeredMessage

[英]Azure Service Bus Queue - QueueClient.Receive() returning null BrokeredMessage when messages are in the queue

I have messages in an Azure Service Bus Queue that I can't receive. 我在Azure服务总线队列中收到无法接收的消息。 And I'm not getting any indicator as to what the problem is. 而且我没有任何有关问题所在的指标。 I think it has something to do with message size. 我认为这与邮件大小有关。 You can see from the code below that I'm using OpenFileDialog. 您可以从下面的代码中看到我正在使用OpenFileDialog。 I'm selecting jpeg images and they are getting sent to the queue. 我正在选择jpeg图像,它们正被发送到队列中。 Now, when I send small images less than about 50KB, they are getting displayed fine by the receiving process, but larger ones over 100KB are just staying in the queue. 现在,当我发送小于50KB的小图像时,在接收过程中它们可以很好地显示,但是大于100KB的大图像则只留在队列中。 MSDN says that message size limit is 256KB so I'm not sure what is going on here. MSDN说消息大小限制为256KB,所以我不确定这里发生了什么。

I have two classes. 我有两节课。 One is SendToQueue and the other is RecvFromQueue. 一个是SendToQueue,另一个是RecvFromQueue。 Here is the code. 这是代码。

using System;
using System.IO;
using System.Windows.Forms;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.WindowsAzure;

namespace ServiceBusQueueApp
{
    public class SendToQueue
    {
        private const string c_testqueue = "TestQueue";

        [STAThreadAttribute]
        static void Main(string[] args)
        {
            // Configure Queue Settings
            QueueDescription qd = new QueueDescription(c_testqueue)
            {
                MaxSizeInMegabytes = 5120,
                DefaultMessageTimeToLive = new TimeSpan(1, 1, 0)
            };

            // Create a new Queue with custom settings
            string connectionString =
                CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");

            var namespaceManager =
                NamespaceManager.CreateFromConnectionString(connectionString);

            if (!namespaceManager.QueueExists(c_testqueue))
            {
                namespaceManager.CreateQueue(qd);
            }

            namespaceManager.DeleteQueue(qd.Path);
            namespaceManager.CreateQueue(qd);

            QueueClient client = QueueClient.CreateFromConnectionString(connectionString, c_testqueue);

            double maxSize = Math.Pow(2, 18);

            OpenFileDialog openFile = new OpenFileDialog();
            while (true)
            {
                if (openFile.ShowDialog() == DialogResult.Cancel)
                {
                    break;
                }

                var messageBodyStream = new FileStream(openFile.FileName, System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                if (messageBodyStream.Length > maxSize)
                {
                    MessageBox.Show("File is larger than 256KB.");
                    continue;
                }
                BrokeredMessage msg =
                    new BrokeredMessage(messageBodyStream);
                msg.Properties["MyProperty"] = "Test Value";


                try
                {
                    //send msg to the queue
                    client.Send(msg);
                }
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message);
                    throw;
                }
            }

        }
    }
}


using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using Microsoft.WindowsAzure;

namespace ServiceBusQueueApp
{
    class RecvFromQueue
    {

        private const string c_testqueue = "TestQueue";

        static void Main(string[] args)
        {
            // Create a new Queue with custom settings
            string connectionString =
                CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");

            var namespaceManager =
                NamespaceManager.CreateFromConnectionString(connectionString);

            if (!namespaceManager.QueueExists(c_testqueue))
            {
                MessageBox.Show("Queue does not exist.");
                throw new Exception("Queue does not exist.");
            }

            QueueClient client = QueueClient.CreateFromConnectionString(connectionString, c_testqueue);

            while (true)
            {
                BrokeredMessage message = client.Receive();

                if (message == null)
                {
                    continue;
                }
                try
                {
                    Stream fstream = message.GetBody<Stream>();
                    byte[] buffer = new byte[fstream.Length];
                    fstream.Read(buffer, 0, (int)fstream.Length);
                    File.WriteAllBytes(@"C:\users\roberthar\pictures\testpic.png", buffer);
                    fstream.Close();

                    Process paint = new Process();
                    paint.StartInfo.FileName = @"C:\Windows\System32\mspaint.exe";
                    paint.StartInfo.Arguments = @"C:\users\roberthar\pictures\testpic.png";
                    paint.Start();

                    Thread.Sleep(3000);

                    paint.Close();

                    // Remove message from queue
                    message.Complete();
                }
                catch (Exception exception)
                {
                    // Indicate a problem, unlock message in queue
                    message.Abandon();
                }
            }
        }
    }
}

Message size limit is 256 KB but this includes both the headers and the body, where the maximum header size is 64 KB . 邮件大小限制为256 KB,但这包括标头和正文,最大标头大小为64 KB In your case header is not an issue (less than 1 KB) 在您的情况下,标题不是问题(小于1 KB)

I run your example with few minor changes: 我运行您的示例时,做了一些小的更改:

            string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                string.Format("testpic_{0}_{1}_{2}.png", now.Hour, now.Minute, now.Second));
            File.WriteAllBytes(filePath, buffer);
            fstream.Close();

            Process paint = new Process();
            paint.StartInfo.FileName = @"C:\Windows\System32\mspaint.exe";
            paint.StartInfo.Arguments = filePath;
            paint.Start();

And I was able to successfully send and receive message with this 254 KB image 而且我能够使用此254 KB图像成功发送和接收消息

If your message would be too large you would get MessageSizeExceededException when you call client.Send(msg); 如果您的消息太大,则在调用client.Send(msg);时会收到MessageSizeExceededException client.Send(msg);

You can run this test on your queue to see if you can receive all messages, it passes for me. 您可以在队列上运行此测试,以查看是否可以接收所有消息,它对我来说是合格的。

    [Fact]
    public void MaxMessageSize()
    {
        var sender = CreateClient();
        var reciver = CreateClient();
        for (int i = 1; i < 255; i++)
        {
            var size = i*1024;
            var buffer = new byte[size];
            random.NextBytes(buffer);
             BrokeredMessage msg =
               new BrokeredMessage(buffer);
            msg.Properties["size"] = size;
            sender.Send(msg);
            var message  = reciver.Receive();
            Assert.NotNull(message);
            Assert.Equal(message.Properties["size"], size);
            var bufferReceived = message.GetBody<byte[]>();
            Assert.Equal(buffer, bufferReceived);
            message.Complete();
        }
    }

Full gist here 要点在这里

I stumbled upon this question helping a co-worker. 我偶然发现了这个问题,为同事提供了帮助。 (I promise it was another dev!) (我保证这是另一个开发者!)

We ran into this issue while he was running code that checked the queue.MessageCount (setting it to a variable of name myQMessageCount ) and the code had "while (myQMessageCount > 0)" and he was resetting the queuecount after every msg.Complete (inside the same while loop) 当他运行检查队列的代码时,我们遇到了这个问题。MessageCount(将其设置为名为myQMessageCount的变量),并且代码具有“ while(myQMessageCount> 0)”,并且他在每个msg.Complete(在相同的while循环内)

Turns out .MessageCount is a "sum" of all messages in the queue, including Active (the ones you should be able to read) and dead letters and others. 原来,.MessageCount是队列中所有消息的“总和”,包括活动(您应该能够阅读的消息),不活动的字母和其他消息。

So (1), the fix was for him to change his code to check the ActiveMessageCount, not the .MessageCount 因此(1),解决方法是让他更改代码以检查ActiveMessageCount,而不是.MessageCount

                Microsoft.ServiceBus.Messaging.QueueDescription qd = myMicrosoftdotServiceBusdotNamespaceManager.GetQueue(qName);
                string deadLetterQueueName = QueueClient.FormatDeadLetterPath(qd.Path);
                int activeMessageCount = qd.MessageCountDetails.ActiveMessageCount;
                int deadLetterMessageCount = qd.MessageCountDetails.DeadLetterMessageCount;
                int scheduledMessageCount = qd.MessageCountDetails.ScheduledMessageCount;
                int transferDeadLetterMessageCount = qd.MessageCountDetails.TransferDeadLetterMessageCount;
                int transferMessageCount = qd.MessageCountDetails.TransferMessageCount;

and (2), after we discussed it, it probably isn't wise to keep checking the ActiveMessageCount, and just let a returned null BrokeredMessage be the check that there are no more messages in the queue. (2),在我们讨论之后,继续检查ActiveMessageCount是不明智的,只让返回的null BrokeredMessage作为检查队列中是否没有消息的检查。

Anyway. 无论如何。 I am posting this answer here for future readers who might get stuck on some custom read-queue code they are writing. 我将这个答案发布在这里,供将来的读者使用,他们可能会陷入他们正在编写的一些自定义阅读队列代码中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Azure Service Bus Queue和BrokeredMessage.ScheduledEnqueueTimeUtc续订订阅 - using an Azure Service Bus Queue and BrokeredMessage.ScheduledEnqueueTimeUtc to renew subscriptions 调用QueueClient.CreateFromConnectionString时使用C#的Azure服务总线队列:BadImageFormatException - Azure Service bus Queue using C# : BadImageFormatException when calling QueueClient.CreateFromConnectionString 同步读取azure服务总线QUEUE消息 - Read azure service bus QUEUE messages synchronously brokeredmessage微软服务总线队列ReceiveBatch无法获取所有死信消息 - brokeredmessage microsoft service bus queue ReceiveBatch not obtaining all dead letter messages 将消息从 Azure 服务总线队列发送到新的 asb 队列 - Send messages from Azure Service Bus queue to new asb queue Azure 服务总线 | 重新处理死信消息返回队列 | 如何接收来自死信队列的所有消息? - Azure service bus | Re process dead letter messages back to queue | How to receive all messages from dead letter queue? 如何测试QueueClient是否可以成功连接到Azure服务总线队列? - How can I test if QueueClient can successfully connect to an Azure Service Bus Queue? 使用 BrokeredMessage 从 Azure 服务总线队列 (v1) 反序列化强类型对象 - Deserialize strongly typed object from Azure Service Bus Queue (v1) using BrokeredMessage Azure服务总线队列 - Azure Service Bus Queue QueueClient.Receive()的异步方法? - Asynchronous method for QueueClient.Receive()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM