如何在C#中通过MSMQ发送和接收LIST对象?
No worries, this is totally doable—MSMQ works great with collections as long as you handle serialization properly. Let's break this down with concrete examples, starting from setup to full send/receive code.
First, Prerequisites
- Make sure you have the System.Messaging assembly referenced in your project (right-click project → Add → Reference → Search for System.Messaging).
- Any custom objects in your list must be marked with the
[Serializable]attribute—this lets MSMQ convert the object to a stream for transport.
Step 1: Define a Serializable Model
Let's use a simple Person class as the item in our list. If you're using your own object, just add the [Serializable] attribute:
using System; [Serializable] public class Person { public string Name { get; set; } public int Age { get; set; } public override string ToString() { return $"Name: {Name}, Age: {Age}"; } }
Step 2: Sending a List to MSMQ
We'll first check if the queue exists (create it if not), then configure the message formatter, and send our list as a message.
using System.Collections.Generic; using System.Messaging; public static void SendListToMsmq() { // Define your queue path (local machine example; use @".\Private$\MyPersonQueue" for private queues) string queuePath = @".\Private$\PersonListQueue"; // Create queue if it doesn't exist if (!MessageQueue.Exists(queuePath)) { MessageQueue.Create(queuePath); Console.WriteLine("Queue created successfully."); } // Initialize the queue using (var queue = new MessageQueue(queuePath)) { // Set the formatter to XmlMessageFormatter (matches the type we're sending) queue.Formatter = new XmlMessageFormatter(new[] { typeof(List<Person>) }); // Create our list of Person objects var peopleList = new List<Person> { new Person { Name = "Alice", Age = 30 }, new Person { Name = "Bob", Age = 25 }, new Person { Name = "Charlie", Age = 35 } }; // Send the list as a message queue.Send(peopleList, "List of People"); Console.WriteLine("List sent to MSMQ successfully!"); } }
Step 3: Receiving the List from MSMQ
To receive, we need to use the same formatter as when sending, so MSMQ can deserialize the message back into our List
Option 1: Synchronous Receive (Blocks until a message arrives)
public static List<Person> ReceiveListFromMsmq() { string queuePath = @".\Private$\PersonListQueue"; if (!MessageQueue.Exists(queuePath)) { Console.WriteLine("Queue does not exist!"); return null; } using (var queue = new MessageQueue(queuePath)) { // Critical: Use the same formatter as sending queue.Formatter = new XmlMessageFormatter(new[] { typeof(List<Person>) }); try { // Receive the message (blocks until one is available) var message = queue.Receive(); var receivedList = message.Body as List<Person>; if (receivedList != null) { Console.WriteLine("\nReceived List:"); foreach (var person in receivedList) { Console.WriteLine(person.ToString()); } } return receivedList; } catch (MessageQueueException ex) { Console.WriteLine($"Error receiving message: {ex.Message}"); return null; } } }
Option 2: Asynchronous Receive (Non-blocking)
If you don't want to block your thread, use an asynchronous receive:
public static void ReceiveListAsync() { string queuePath = @".\Private$\PersonListQueue"; if (!MessageQueue.Exists(queuePath)) { Console.WriteLine("Queue does not exist!"); return; } using (var queue = new MessageQueue(queuePath)) { queue.Formatter = new XmlMessageFormatter(new[] { typeof(List<Person>) }); // Register the async receive handler queue.ReceiveCompleted += (sender, e) => { try { var message = queue.EndReceive(e.AsyncResult); var receivedList = message.Body as List<Person>; if (receivedList != null) { Console.WriteLine("\nAsync Received List:"); foreach (var person in receivedList) { Console.WriteLine(person.ToString()); } } // Start listening for the next message queue.BeginReceive(); } catch (MessageQueueException ex) { Console.WriteLine($"Async receive error: {ex.Message}"); } }; // Start listening queue.BeginReceive(); Console.WriteLine("Waiting for async messages... Press any key to exit."); Console.ReadKey(); } }
Step 4: Test It All
Call these methods from your main program:
class Program { static void Main(string[] args) { // Send the list SendListToMsmq(); // Receive synchronously ReceiveListFromMsmq(); // Or uncomment to test async receive // ReceiveListAsync(); } }
Key Notes
- Always use the same formatter (Xml or Binary) for send and receive—mixing them will cause deserialization errors.
- For private queues, use the path format
@".\Private$\QueueName". For remote queues, use@"ServerName\Private$\QueueName". - If you prefer binary serialization (smaller message size, faster), replace
XmlMessageFormatterwithBinaryMessageFormatter—just make sure both send and receive use it.
内容的提问来源于stack exchange,提问作者user3063679

