2009-03-17 12 views
25

मैं सी # में एक संदेश कतार में संदेशों लिख रहा हूँ इस प्रकार है:संदेश कतार त्रुटि: एक फ़ॉर्मेटर पढ़ने संदेश में सक्षम नहीं मिल सकता है

queue.Send(new Message("message")); 

मैं इस प्रकार संदेशों को पढ़ने की कोशिश कर रहा हूँ:

Messages messages = queue.GetAllMessages(); 
foreach(Message m in messages) 
{ 
    String message = m.Body; 
    //do something with string 
} 

हालांकि मुझे एक त्रुटि संदेश मिल रहा है जो कहता है: "इस संदेश को पढ़ने में सक्षम एक फॉर्मेटर नहीं मिल रहा है।"

मैं क्या गलत कर रहा हूं?

उत्तर

35

मैंने प्रत्येक संदेश में एक फॉर्मेटर जोड़कर समस्या हल की। कतार में एक फॉर्मेटर जोड़ना काम नहीं किया।

Messages messages = queue.GetAllMessages(); 
foreach(Message m in messages) 
{ 
    m.Formatter = new XmlMessageFormatter(new String[] { "System.String,mscorlib" }); 
    String message = m.Body; 

    //do something with string 
} 
+0

बिल्कुल सही! बस मैं क्या चाहता था। – NLV

25

या आप

message.Formatter = 
    new System.Messaging.XmlMessageFormatter(new Type[1] { typeof(string) }); 
+2

मुझे लगता है कि यह स्वीकृत उत्तर के लिए बेहतर है। स्ट्रिंग के रूप में पूर्ण प्रकार के नाम को निर्दिष्ट करने की तुलना में यह अधिक "मजबूत" है। –

2

ऐसा लगता है कि क्रमबद्धता केवल जब संदेश वर्ग के शरीर प्रॉपर्टी एक्सेस किया जाता है का उपयोग कर सकते हैं। जब तक आप संदेश पर सेट करने के बाद बॉडी प्रॉपर्टी तक पहुंचते हैं, तो सही फॉर्मेटर यह ठीक काम करता है।

यदि आप प्रत्येक संदेश के लिए फॉर्मेटर नहीं बनाना चाहते हैं तो आप कतार पर फॉर्मेटर सेट कर सकते हैं और प्रत्येक संदेश (बॉडी प्रॉपर्टी तक पहुंचने से पहले) को कतार के फॉर्मेटर से फॉर्मेटर संपत्ति सेट कर सकते हैं।

_queue.Send(new Message() { Formatter = _queue.Formatter, Body = myData }); 

var msg = _qeueu.Receive(); 
msg.Formatter = _queue.Formatter; 
var myObject = (MyClass) msg.Body; 
5

आप शरीर के बजाय संदेश की bodystream पढ़ने, इस तरह की कोशिश कर सकते:

StreamReader sr = new StreamReader(m.BodyStream);  
string messageBody = "";  
while (sr.Peek() >= 0) 
{ 
    messageBody += sr.ReadLine(); 
} 
+1

'StreamReader' क्लास में एक विधि' ReadToEnd' है जो 'स्ट्रिंग' ऑब्जेक्ट्स की श्रृंखला को लूपिंग और निर्माण करने से बेहतर प्रदर्शन करेगी। –

2
Message recoverableMessage = new Message(); 
recoverableMessage.Body = "Sample Recoverable Message"; 

recoverableMessage.Formatter = new XmlMessageFormatter(new String[] {"System.String,mscorlib" }); 

MessageQueue myQueue = new MessageQueue(@".\private$\teste"); 

कतार फ़ॉर्मेटर भी सेट किया जाना चाहिए।

myQueue.Formatter = new XmlMessageFormatter(new String[] { "System.String,mscorlib" }); 
0
इस

बहुत ठीक काम करता है:

static readonly XmlMessageFormatter f = new XmlMessageFormatter(new Type[] { typeof(String) }); 

private void Client() 
{ 
    var messageQueue = new MessageQueue(@".\Private$\SomeTestName"); 

    foreach (Message message in messageQueue.GetAllMessages()) 
    { 
     message.Formatter = f; 
     Console.WriteLine(message.Body); 
    } 
    messageQueue.Purge(); 
} 
2

हर कोई यहाँ समाधान प्रदान करने में एक शानदार काम किया है, और बस समाप्त होने से इस समस्या को अपने आप को मैं में अपने ही 2c फेंक और समाधान दिखाना चाहते थे जूझ मैं उस काम के साथ बहुत अच्छी तरह से आया था।

queue.SetPermissions("Everyone", MessageQueueAccessRights.FullControl, AccessControlEntryType.Set); 
:

सबसे पहले जब कतार मुझे यकीन है कि मैं इतनी तरह अनुमतियों को खोलने बनाने बनाई गई है (मैं हमारे आवेदन के संदर्भ में कतार सुरक्षा को लेकर चिंतित नहीं हूँ ... यह एक गणना निर्णय होता है)

उस लाइन के बिना मुझे सभी प्रकार की पहुंच योग्य त्रुटियां मिलेंगी और कंप्यूटर प्रबंधन स्क्रीन से कतार ब्राउज़ भी नहीं कर सका।कि संयोग से यदि आप करने के लिए होता है और आप कैसे कतार है कि आप बस करने के लिए पहुँच नहीं है को मारने के लिए सोच रहे हैं:

  1. बंद करो सेवा "संदेश कतार"
  2. गोटो "C: \ Windows \ System32 \ MSMQ \ भंडारण \ lqs "
  3. ओपन नोटपैड में प्रत्येक फ़ाइल और अपने कतार नाम देखने के
  4. कि फ़ाइल हटाएँ और मैसेजिंग सेवा
पुनः आरंभ (यह सबसे अधिक संभावना है कि हाल ही में संशोधित किया गया था फ़ाइल हो जाएगा)

बेस क्लास एफ बनाएं या अपनी कतार संदेश आइटम और इसे चिह्नित करें [Serializable]। आवेदन लोड कैश पर अपने सभी संदेश कुछ इस तरह का उपयोग कर प्रकार की एक सूची:

var types = typeof(QueueItemBase).Assembly 
      .GetTypes() 
      .Where(t => typeof(QueueItemBase).IsAssignableFrom(t) && t.IsAbstract == false) 
      .ToArray(); 
... 
// Create and cache a message formatter instance 
_messageFormatter = new XmlMessageFormatter(types); 

अब आप संदेश प्राप्त करना शुरू करने के लिए तैयार कर रहे हैं। मेरी पहली प्रवृत्ति संदेश के लिए मतदान करना था, लेकिन एपीआई वास्तव में इस तरह काम करना पसंद नहीं करता है। तो मैं एक पृष्ठभूमि धागा बनाता हूं और अवरुद्ध विधि को कॉल करता हूं कतार पर प्राप्त होता है जो संदेश उपलब्ध होने के बाद वापस आ जाएगा। वहाँ संदेश डीकोड से के रूप में सरल है:

var message = queue.Receive(); 
if (message == null) 
    continue; 

// Tell the message about our formatter containing all our message types before we 
// try and deserialise 
message.Formatter = _messageFormatter; 

var item = message.Body as QueueItemBase; 

और वह सब आप अच्छी तरह से लागू करने के लिए MSMQ एकीकरण typesafe जरूरत होना चाहिए!

1

यह मेरे लिए काम किया किसी रिमोट मशीन से एक निजी कतार पढ़ने के लिए:

public void ReceiveAsync<T>(MqReceived<T> mqReceived) 
    { 
     try 
     { 
      receiveEventHandler = (source, args) => 
      { 
       var queue = (MessageQueue)source; 
       using (Message msg = queue.EndPeek(args.AsyncResult)) 
       { 
        XmlMessageFormatter formatter = new XmlMessageFormatter(new Type[] { typeof(T) }); 
        msg.Formatter = formatter; 
        queue.ReceiveById(msg.Id); 
        T tMsg = (T)msg.Body; 
        mqReceived(tMsg); 

       } 
       queue.BeginPeek(); 
      }; 

      messageQueu.PeekCompleted += receiveEventHandler; 
      messageQueu.BeginPeek(); 

     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 
     } 
    } 

आप GitHub पर नमूना कोड और msmq पुस्तकालय देख सकते हैं::

MessageQueue queue = new MessageQueue(@"FormatName:Direct=OS:MACHINENAME\private$\MyQueueName", QueueAccessMode.Peek); 

Message msg = queue.Peek(); 
StreamReader sr = new StreamReader(msg.BodyStream); 
string messageBody = sr.ReadToEnd(); 
संबंधित मुद्दे