2015-07-20 53 views
0

我有寫入到隊列(這裏的代碼)的成分:MSMQ使用的BinaryFormatter

using (MessageQueueTransaction transaction = new MessageQueueTransaction()) 
      { 
       transaction.Begin(); 
       using (var queue = new MessageQueue(@fullQueue, QueueAccessMode.Send)) 
       { 
        BinaryMessageFormatter formatter = new BinaryMessageFormatter(); 
        // XmlMessageFormatter formatter = new XmlMessageFormatter(new Type[] { typeof(Testing) }); 

        var testing = new Testing {myBody = string.Format("Hello {0}",Environment.UserName), myMessageText = "Header"}; 
        var message = new Message 
        { 
         Body = testing, 
         Label = Environment.MachineName, 
         UseDeadLetterQueue = true, 
         Recoverable = true, 
         Formatter = formatter 
        }; 
        queue.Send(message, MessageQueueTransactionType.Single); 

       } 
       transaction.Commit(); 

      } 

現在當運行上述的「測試」簡單地是與在其上2個特性的Serializble對象。如果我查看隊列上的文本正文,它看起來沒問題。

現在我有一個單獨的組件從隊列中讀取:

BinaryMessageFormatter formatter = new BinaryMessageFormatter(); 
     // XmlMessageFormatter formatter = new XmlMessageFormatter(new Type[] { typeof(Testing) }); 
     MessageQueue msgQ = new MessageQueue(fullQueue, QueueAccessMode.Receive); 

     try 
     { 

      using (TransactionScope transaction = new TransactionScope()) 
      { 

       Message incoming = new Message { Formatter = formatter, AcknowledgeType = AcknowledgeTypes.FullReceive }; 

       incoming = msgQ.Receive(new TimeSpan(0, 0, 3),MessageQueueTransactionType.Single); 
       // var ttt = incoming.Body; 
       MemoryStream mem = (MemoryStream) incoming.BodyStream; 
       mem.Seek(0, SeekOrigin.Begin); 
       IFormatter ifm = new BinaryFormatter(); 
       Testing tt = (Testing)ifm.Deserialize(mem); 

       transaction.Complete(); 
      } 

     } 

現在在一點上,我進行ifm.Deserialize,它用錯誤

無法找到程序集「MSMQWrite ,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'其中MSMQWrite是我的寫入組件中的方法名稱。

當寫我想我可能必須先明確序列化對象,以便在我的組件,寫我改變了我的代碼稍有是隊列:

​​

正如你可以看到我設置BodyStream這次直接,但是當我嘗試從隊列中讀取時仍然收到相同的錯誤。

+0

你在每個裝配一個單獨的測試類?如果要使用二進制格式,然後組件必須是共享的(除非你想用它_play_,可能的,只是不容易) –

+0

是,測試類已在這兩個組件複製 – bilpor

+0

你不能在C#(相反,例如,C++)一個類與它的程序集綁定。名字是不夠的。你應該把它移動到一個共享的組件(或_hacking_格式解析爲**另一種類型的**,因爲具有相同名稱的一類是另一個組件是另一種類型) –

回答

0

你需要引用包含從你的第二個組件的測試類的程序集。我猜那個程序集是MSMQWrite。如果您已經引用它,請確保將其複製到第二個組件所在的文件夾,以便在運行時找到它。

其他選項是將實際的類被序列化到不同的組件(例如MSMQCommon)和從兩個您的組件寫入和一個讀數引用它。或者只有一個組件。

+0

我不明白爲什麼我應該有兩種方法一個組件。總的來說,在實時環境中,我在發送服務器上安裝了1個組件,在接收服務器上安裝了另一個完全獨立的物理機器。通過製作一個組件並部署兩次,以便每個組件都可以使用正確的方法顯然是錯誤的。我假設錯誤信息是誤導性的,而這是我錯過的其他東西。鏈接組件的唯一事情就是消息隊列。一個組件方法不需要引用其他組件方法。 – bilpor

+0

您正在使用二進制格式化所以爲了反序列化需要含有完全相同的對象,你序列化,因此,(在相同或所有內容)共享組件的組裝。全部在一個組成部分只是實現相同的一個簡短的方法。如果你想從一個共享類中分離你的組件,你將需要使用不同的序列化器,XML或自定義組件,並且讓你的類以兩種方式知道如何序列化。將DTO移動到共享組件並以兩種方式進行部署應該是最好的。 – Juan

+0

你好,我意識到你的意思。 DTO需要放置在它自己的程序集中,然後由發件人和收件人引用dll現在可以工作了,謝謝。 – bilpor