2014-11-14 135 views
0

我在Azure服務總線隊列中收到我無法接收的郵件。我沒有得到任何問題的指標。我認爲這與郵件大小有關。你可以從下面的代碼中看到我正在使用OpenFileDialog。我正在選擇jpeg圖像,並將它們發送到隊列中。現在,當我發送小於約50KB的小圖片時,它們在接收過程中顯示得很好,但超過100KB的較大圖片只停留在隊列中。 MSDN表示郵件大小限制爲256KB,因此我不確定這裏發生了什麼。Azure服務總線隊列 - QueueClient.Receive()當郵件在隊列中時返回null BrokeredMessage

我有兩個類。一個是SendToQueue,另一個是RecvFromQueue。這是代碼。

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(); 
       } 
      } 
     } 
    } 
} 
+0

對不起,我意識到這是很晚,但我會建議你在接收代碼中添加某種日誌記錄。此代碼捕獲任何異常(與隊列相關或與文件相關),然後放棄該消息而不記錄。除非記錄異常詳細信息,否則不會看到實際的錯誤(因此可以修復它)。 – Joon 2017-04-04 16:09:44

回答

1

消息大小限制爲256 KB但這既包括標頭和主體,其中最大報頭大小是64 KB。在你的情況報頭是不是一個問題(小於1 KB)

我有一些小的變化運行例如:

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

,我能夠與this 254 KB image

成功地發送和接收消息如果你的信息會太大,你會得到MessageSizeExceededException當你調用client.Send(msg);

您可以在隊列中運行這個測試,看看你能收到的所有消息,它傳遞給我。

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

完全gist here

+0

使用您提供的要點(通過從控制檯應用程序運行簡單重構)我無法接收郵件大小超過64kb的郵件。當消息大於256kb時,它只發送失敗 – BFreeman 2015-03-09 20:40:06

0

我偶然發現了這個問題,幫助同事。 (我承諾這是另一個開發!)

當他運行檢查隊列的代碼時,我們遇到了這個問題.MessageCount(將其設置爲名稱爲myQMessageCount的變量)並且代碼具有「while(myQMessageCount> 0) 「並且他在每個msg.Complete(在相同的while循環內)後重置隊列計數

結果.MessageCount是隊列中所有消息的」總和「,包括Active(應該能夠讀取的那些消息)和死信等。

所以(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; 

和(2),我們討論後,它可能不是明智的繼續檢查ActiveMessageCount,並讓返回的空BrokeredMessage成爲檢查隊列中沒有更多消息的檢查。

無論如何。我將這個答案發布給未來的讀者,他們可能會遇到他們正在編寫的一些自定義讀取隊列代碼。