Verwenden von Warteschlangen für unzustellbare Nachrichten zur Handhabung von NachrichtenübertragungsfehlernUsing Dead-Letter Queues to Handle Message Transfer Failures

Die Zustellung von in der Warteschlange stehenden Nachrichten kann fehlschlagen.Queued messages can fail delivery. Diese fehlgeschlagenen Nachrichten werden in einer Warteschlange für unzustellbare Nachrichten aufgezeichnet.These failed messages are recorded in a dead-letter queue. Das Fehlschlagen der Zustellung kann beispielsweise durch Netzwerkfehler, eine gelöschte Warteschlange, eine volle Warteschlange, einen Authentifizierungsfehler oder eine zu späte Zustellung verursacht werden.The failed delivery can be caused by reasons such as network failures, a deleted queue, a full queue, authentication failure, or a failure to deliver on time.

In der Warteschlange stehende Nachrichten können über lange Zeit hinweg in der Warteschlange verbleiben, wenn die empfangende Anwendung sie nicht umgehend aus der Warteschlange liest.Queued messages can remain in the queue for a long time if the receiving application does not read them from the queue in a timely fashion. Dieses Verhalten ist möglicherweise nicht für zeitempfindliche Nachrichten geeignet.This behavior may not be appropriate for time-sensitive messages. Zeitempfindliche Nachrichten verfügen über eine Eigenschaft für die Gültigkeitsdauer (Time to Live, TTL), die in der Bindung der Warteschlange festgelegt ist und angibt, wie lange die Nachrichten in der Warteschlange verbleiben können, bevor sie ablaufen.Time-sensitive messages have a Time to Live (TTL) property set in the queued binding, which indicates how long the messages can be in the queue before they must expire. Abgelaufene Nachrichten werden an eine spezielle Warteschlange gesendet und zwar an die Warteschlange für unzustellbare Nachrichten.Expired messages are sent to a special queue called the dead-letter queue. Nachrichten können auch aus anderen Gründen in einer Warteschlange für unzustellbare Nachrichten platziert werden, z. B. aufgrund des Überschreitens eines Warteschlangenkontingents oder aufgrund eines Authentifizierungsfehlers.Messages can also be put in a dead-letter queue for other reasons, such as exceeding a queue quota or because of authentication failure.

Im Allgemeinen schreiben Anwendungen Entschädigungslogik, um Nachrichten aus der Warteschlange für unzustellbare Nachrichten sowie Fehlerursachen zu lesen.Generally, applications write compensation logic to read messages from the dead-letter queue and failure reasons. Die Entschädigungslogik hängt von der Ursache des Fehlers ab.The compensation logic depends on the cause of the failure. Im Falle eines Authentifizierungsfehlers können Sie beispielsweise das an die Nachricht angehängte Zertifikat korrigieren und die Nachricht anschließend erneut senden.For example, in the case of authentication failure, you can correct the certificate attached with the message and resend the message. Wenn eine Zustellung fehlgeschlagen ist, weil das Zielwarteschlangenkontingent nicht erreicht wurde, können Sie erneut einen Zustellungsversuch vornehmen, in der Hoffnung, dass das Kontingentproblem behoben wurde.If delivery failed because the target queue quota was reached, you can reattempt delivery in the hope that the quota problem was resolved.

Die meisten Warteschlangensysteme haben eine systemweite Warteschlange für unzustellbare Nachrichten, in der alle fehlgeschlagenen Nachrichten dieses Systems gespeichert werden.Most queuing systems have a system-wide dead-letter queue where all failed messages from that system are stored. Message Queuing (MSMQ) bietet zwei systemweite Warteschlangen für unzustellbare Nachrichten: eine transaktionale systemweite Warteschlange für unzustellbare Nachrichten, die Nachrichten speichert, die nicht an die transaktionale Warteschlange gesendet werden konnten, und eine nicht transaktionale Warteschlange für unzustellbare Nachrichten, die Nachrichten speichert, die nicht an die nicht transaktionale Warteschlange gesendet werden konnten.Message Queuing (MSMQ) provides two system-wide dead-letter queues: a transactional system-wide dead-letter queue that stores messages that failed delivery to the transactional queue and a non-transactional system-wide dead-letter queue that stores messages that failed delivery to the non-transactional queue. Wenn zwei Clients Nachrichten an zwei verschiedene Dienste senden und deshalb verschiedene Warteschlangen in WCF den gleichen MSMQ-Dienst zum Senden Treiberressourcen, ist es möglich, eine Mischung aus Nachrichten in der Systemwarteschlange für unzustellbare haben.If two clients are sending messages to two different services, and therefore different queues in WCF are sharing the same MSMQ service to send, then it is possible to have a mix of messages in the system dead-letter queue. Dies ist nicht immer optimal.This is not always optimal. In vielen Fällen (z. B. im Hinblick auf die Sicherheit) ist es nicht ratsam, dass ein Client die Nachrichten eines anderen Clients aus der Warteschlange für unzustellbare Nachrichten liest.In several cases (security, for example), you may not want one client to read another client's messages from a dead-letter queue. Bei einer gemeinsam genutzten Warteschlange für unzustellbare Nachrichten müssen die Clients darüber hinaus die Warteschlange nach von ihnen gesendeten Nachrichten durchsuchen, was je nach Anzahl der Nachrichten in der Warteschlange für unzustellbare Nachrichten viel zu aufwendig sein kann.A shared dead-letter queue also requires clients to browse through the queue to find a message that they sent, which can be prohibitively expensive based on the number of messages in the dead-letter queue. Aus diesem Grund in WCFNetMsmqBinding, MsmqIntegrationBinding, und MSMQ auf Windows VistaWindows Vista Geben Sie eine benutzerdefinierte Warteschlange für unzustellbare (auch als eine anwendungsspezifische Dead Letter-Warteschlange bezeichnet).Therefore, in WCFNetMsmqBinding, MsmqIntegrationBinding, and MSMQ on Windows VistaWindows Vista provide a custom dead-letter queue (sometimes referred to as an application-specific dead-letter queue).

Die benutzerdefinierte Warteschlange für unzustellbare Nachrichten ermöglicht eine Isolation zwischen Clients, die den gleichen MSMQ-Dienst verwenden, um Nachrichten zu senden.The custom dead-letter queue provides isolation between clients that share the same MSMQ service to send messages.

Auf Windows Server 2003Windows Server 2003 und Windows XPWindows XP, Windows Communication Foundation (WCF) bietet eine systemweite Warteschlange für alle in der Warteschlange-Clientanwendungen.On Windows Server 2003Windows Server 2003 and Windows XPWindows XP, Windows Communication Foundation (WCF) provides a system-wide dead-letter queue for all queued client applications. Auf Windows VistaWindows Vista, WCF bietet eine Dead Letter-Warteschlange für jede in der Warteschlange stehende Clientanwendung.On Windows VistaWindows Vista, WCF provides a dead-letter queue for each queued client application.

Angeben der Verwendung der Warteschlange für unzustellbare NachrichtenSpecifying Use of the Dead-Letter Queue

Eine Warteschlange für unzustellbare Nachrichten befindet sich im Warteschlangen-Manager der sendenden Anwendung.A dead-letter queue is in the queue manager of the sending application. Sie speichert Nachrichten, die abgelaufen sind oder nicht zugestellt werden konnten.It stores messages that have expired or that have failed transfer or delivery.

Die Bindung weist die folgenden Eigenschaften für eine Warteschlange für unzustellbare Nachrichten auf:The binding has the following dead-letter queue properties:

Lesen von Nachrichten aus der Warteschlange für unzustellbare NachrichtenReading Messages from the Dead-Letter Queue

Eine Anwendung, die aus einer Warteschlange für unzustellbare Nachrichten liest ist vergleichbar mit einem WCF-Dienst, der aus einer Anwendungswarteschlange, mit Ausnahme der folgenden geringfügige Unterschiede liest:An application that reads messages out of a dead-letter queue is similar to a WCF service that reads from an application queue, except for the following minor differences:

  • Zum Lesen von Nachrichten aus einer transaktionalen Systemwarteschlange für unzustellbare Nachrichten muss der URI (Uniform Resource Identifier) folgendes Format aufweisen: net.msmq://localhost/system$;DeadXact.To read messages from a system transactional dead-letter queue, the Uniform Resource Identifier (URI) must be of the form: net.msmq://localhost/system$;DeadXact.

  • Zum Lesen von Nachrichten aus einer nicht transaktionalen Systemwarteschlange für unzustellbare Nachrichten muss der URI folgendes Format aufweisen: net.msmq://localhost/system$;DeadLetter.To read messages from a system non-transactional dead-letter queue, the URI must be of the form: net.msmq://localhost/system$;DeadLetter.

  • Um eine benutzerdefinierte Warteschlange für unzustellbare Nachrichten gelesen werden kann, muss der URI von der Form: Net.msmq://localhost/private/<benutzerdefinierte Dlq Namen>, in denen benutzerdefinierte Dlq Namen ist der Name des benutzerdefinierten Dead Letter-Warteschlange.To read messages from a custom dead-letter queue, the URI must be of the form:net.msmq://localhost/private/<custom-dlq-name> where custom-dlq-name is the name of the custom dead-letter queue.

Weitere Informationen zu Adresse Warteschlangen finden Sie unter Dienstendpunkte und Adressieren von Warteschlangen.For more information about how to address queues, see Service Endpoints and Queue Addressing.

Der WCF-Stapel beim Empfänger entspricht Adressen, die der Dienst überwacht wird mit der Adresse für die Nachricht.The WCF stack on the receiver matches addresses that the service is listening on with the address on the message. Wenn die Adressen übereinstimmen, wird die Nachricht weitergeleitet; stimmen sie nicht überein, wird die Nachricht nicht weitergeleitet.If the addresses match, the message is dispatched; if not, the message is not dispatched. Dies kann Probleme beim Lesen aus der Warteschlange für unzustellbare Nachrichten verursachen, da die Nachrichten in der Warteschlange in der Regel an den Dienst und nicht an den Dienst der Warteschlange für unzustellbare Nachrichten adressiert sind.This can cause problems when reading from the dead-letter queue, because messages in the dead-letter queue are typically addressed to the service and not the dead-letter queue service. Daher muss der Dienst, der aus der Warteschlange für unzustellbare Nachrichten liest, einen Adressfilter ServiceBehavior installieren, der den Stapel auffordert, alle Nachrichten in der Warteschlange unabhängig vom Adressaten abzugleichen.Therefore, the service reading from the dead-letter queue must install an address filter ServiceBehavior that instructs the stack to match all messages in the queue independently of the addressee. Genau genommen müssen Sie dem Dienst, der die Nachrichten aus der Warteschlange für unzustellbare Nachrichten liest, ein ServiceBehavior mit dem Parameter Any hinzufügen.Specifically, you must add a ServiceBehavior with the Any parameter to the service reading messages from the dead-letter queue.

Die Handhabung von beschädigten Nachrichten aus der Warteschlange für unzustellbare NachrichtenPoison Message Handling from the Dead-Letter Queue

Die Handhabung beschädigter Nachrichten ist für Warteschlangen für unzustellbare Nachrichten verfügbar. Dabei gelten bestimmte Voraussetzungen.Poison message handling is available on dead-letter queues, with some conditions. Da beim Lesen aus der Systemwarteschlange für unzustellbare Nachrichten keine untergeordneten Warteschlangen erstellt werden können, kann ReceiveErrorHandling nicht auf Move festgelegt werden.Because you cannot create sub-queues from system queues, when reading from the system dead-letter queue, the ReceiveErrorHandling cannot be set to Move. Beachten Sie, dass Sie beim Lesen aus einer benutzerdefinierten Warteschlange für unzustellbare Nachrichten untergeordnete Warteschlangen nutzen können und dass Move daher eine gültige Disposition für die beschädigte Nachricht ist.Note that if you are reading from a custom dead-letter queue, you can have sub-queues and, therefore, Move is a valid disposition for the poison message.

Wenn ReceiveErrorHandling beim Lesen aus der benutzerdefinierten Warteschlange für unzustellbare Nachrichten auf Reject eingestellt ist, wird die beschädigte Nachricht in der Systemwarteschlange für unzustellbare Nachrichten platziert.When ReceiveErrorHandling is set to Reject, when reading from the custom dead letter queue, the poison message is put in the system dead-letter queue. Beim Lesen aus der Systemwarteschlange für unzustellbare Nachrichten wird die Nachricht abgelegt (gelöscht).If reading from the system dead-letter queue, the message is dropped (purged). Ein Ausschluss aus einer Systemwarteschlange für unzustellbare Nachrichten in MSMQ legt die Nachricht ab (löscht sie).A reject from a system dead-letter queue in MSMQ drops (purges) the message.

BeispielExample

Im folgenden Beispiel wird gezeigt, wie eine Warteschlange für unzustellbare Nachrichten erstellt und für die Verarbeitung abgelaufener Nachrichten verwendet wird.The following example shows how to create a dead-letter queue and how to use it to process expired messages. Das Beispiel basiert auf dem Beispiel in Vorgehensweise: Exchange in der Warteschlange Nachrichten mit WCF-Endpunkten.The example is based on the example in How to: Exchange Queued Messages with WCF Endpoints. Im folgenden Beispiel wird dargestellt, wie der Clientcode auf den Dienst für die Auftragsverarbeitung geschrieben wird, der für jede Anwendung eine Warteschlange für unzustellbare Nachrichten verwendet.The following example shows how to write the client code to the order processing service that uses a dead-letter queue for each application. Im Beispiel wird auch gezeigt, wie Nachrichten aus der Warteschlange für unzustellbare Nachrichten verarbeitet werden.The example also shows how to process messages from the dead-letter queue.

Der folgende Code ist für einen Client, der eine Warteschlange für unzustellbare Nachrichten für jede Anwendung angibt.The following is code for a client that specifies a dead-letter queue for each application.

using System;
using System.ServiceModel.Channels;
using System.Configuration;
//using System.Messaging;
using System.ServiceModel;
using System.Transactions;

namespace Microsoft.ServiceModel.Samples
{
	
    //The service contract is defined in generatedProxy.cs, generated from the service by the svcutil tool.

    //Client implementation code.
    class Client
    {
        static void Main()
        {
            // Get MSMQ queue name from appsettings in configuration.
            string deadLetterQueueName = ConfigurationManager.AppSettings["deadLetterQueueName"];

            // Create the transacted MSMQ queue for storing dead message if necessary.
            if (!System.Messaging.MessageQueue.Exists(deadLetterQueueName))
                System.Messaging.MessageQueue.Create(deadLetterQueueName, true);

     
            OrderProcessorClient client = new OrderProcessorClient("OrderProcessorEndpoint");
	    try
            {	

            
                // Create the purchase order.
                PurchaseOrder po = new PurchaseOrder();
                po.CustomerId = "somecustomer.com";
                po.PONumber = Guid.NewGuid().ToString();

                PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
                lineItem1.ProductId = "Blue Widget";
                lineItem1.Quantity = 54;
                lineItem1.UnitCost = 29.99F;

                PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
                lineItem2.ProductId = "Red Widget";
                lineItem2.Quantity = 890;
                lineItem2.UnitCost = 45.89F;

                po.orderLineItems = new PurchaseOrderLineItem[2];
                po.orderLineItems[0] = lineItem1;
                po.orderLineItems[1] = lineItem2;

                //Create a transaction scope.
                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
                {
                    // Make a queued call to submit the purchase order.
                    client.SubmitPurchaseOrder(po);
                    // Complete the transaction.
                    scope.Complete();
                }


                client.Close();
            }
            catch(TimeoutException timeout)
            {
		Console.WriteLine(timeout.Message);
                client.Abort();
	    }
            catch(CommunicationException conexcp)
            {
		Console.WriteLine(conexcp.Message);
                client.Abort();
	    }

            Console.WriteLine();
            Console.WriteLine("Press <ENTER> to terminate client.");
            Console.ReadLine();
        }
    }
}
Imports System
Imports System.ServiceModel.Channels
Imports System.Configuration
'using System.Messaging;
Imports System.ServiceModel
Imports System.Transactions

Namespace Microsoft.ServiceModel.Samples

	'The service contract is defined in generatedProxy.cs, generated from the service by the svcutil tool.

	'Client implementation code.
	Friend Class Client
		Shared Sub Main()
			' Get MSMQ queue name from appsettings in configuration.
			Dim deadLetterQueueName As String = ConfigurationManager.AppSettings("deadLetterQueueName")

			' Create the transacted MSMQ queue for storing dead message if necessary.
			If (Not System.Messaging.MessageQueue.Exists(deadLetterQueueName)) Then
				System.Messaging.MessageQueue.Create(deadLetterQueueName, True)
			End If


			Dim client As New OrderProcessorClient("OrderProcessorEndpoint")
		Try


				' Create the purchase order.
				Dim po As New PurchaseOrder()
				po.CustomerId = "somecustomer.com"
				po.PONumber = Guid.NewGuid().ToString()

				Dim lineItem1 As New PurchaseOrderLineItem()
				lineItem1.ProductId = "Blue Widget"
				lineItem1.Quantity = 54
				lineItem1.UnitCost = 29.99F

				Dim lineItem2 As New PurchaseOrderLineItem()
				lineItem2.ProductId = "Red Widget"
				lineItem2.Quantity = 890
				lineItem2.UnitCost = 45.89F

				po.orderLineItems = New PurchaseOrderLineItem(1){}
				po.orderLineItems(0) = lineItem1
				po.orderLineItems(1) = lineItem2

				'Create a transaction scope.
				Using scope As New TransactionScope(TransactionScopeOption.Required)
					' Make a queued call to submit the purchase order.
					client.SubmitPurchaseOrder(po)
					' Complete the transaction.
					scope.Complete()
				End Using


				client.Close()
			Catch timeout As TimeoutException
		Console.WriteLine(timeout.Message)
				client.Abort()
			Catch conexcp As CommunicationException
		Console.WriteLine(conexcp.Message)
				client.Abort()
			End Try

			Console.WriteLine()
			Console.WriteLine("Press <ENTER> to terminate client.")
			Console.ReadLine()
		End Sub
	End Class
End Namespace

Der folgende Code ist für die Clientkonfigurationsdatei.The following is code for the client configuration file.

Der folgende Code ist für einen Dienst, der Nachrichten aus einer Warteschlange für unzustellbare Nachrichten verarbeitet.The following is code for a service processing messages from a dead-letter queue.

using System;
using System.ServiceModel.Description;
using System.Configuration;
using System.Messaging;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Transactions;

namespace Microsoft.ServiceModel.Samples
{
    // Define a service contract. 
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface IOrderProcessor
    {
        [OperationContract(IsOneWay = true)]
        void SubmitPurchaseOrder(PurchaseOrder po);
    }

    // Service class that implements the service contract.
    // Added code to write output to the console window
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single, AddressFilterMode = AddressFilterMode.Any)]
    public class PurchaseOrderDLQService : IOrderProcessor
    {
        OrderProcessorClient orderProcessorService;
        public PurchaseOrderDLQService()
        {
            orderProcessorService = new OrderProcessorClient("OrderProcessorEndpoint");
        }

        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void SimpleSubmitPurchaseOrder(PurchaseOrder po)
        {
            Console.WriteLine("Submitting purchase order did not succeed ", po);
            MsmqMessageProperty mqProp = OperationContext.Current.IncomingMessageProperties[MsmqMessageProperty.Name] as MsmqMessageProperty;

            Console.WriteLine("Message Delivery Status: {0} ", mqProp.DeliveryStatus);
            Console.WriteLine("Message Delivery Failure: {0}", mqProp.DeliveryFailure);
            Console.WriteLine();
        }

        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void SubmitPurchaseOrder(PurchaseOrder po)
        {
            Console.WriteLine("Submitting purchase order did not succeed ", po);
            MsmqMessageProperty mqProp = OperationContext.Current.IncomingMessageProperties[MsmqMessageProperty.Name] as MsmqMessageProperty;

            Console.WriteLine("Message Delivery Status: {0} ", mqProp.DeliveryStatus);
            Console.WriteLine("Message Delivery Failure: {0}", mqProp.DeliveryFailure);
            Console.WriteLine();

            // Resend the message if timed out.
            if (mqProp.DeliveryFailure == DeliveryFailure.ReachQueueTimeout ||
                mqProp.DeliveryFailure == DeliveryFailure.ReceiveTimeout)
            {
                // Re-send.
                Console.WriteLine("Purchase order Time To Live expired");
                Console.WriteLine("Trying to resend the message");

                // Reuse the same transaction used to read the message from dlq to enqueue the message to the application queue.
                orderProcessorService.SubmitPurchaseOrder(po);
                Console.WriteLine("Purchase order resent");
            }
        }

        // Host the service within this EXE console application.
        public static void Main()
        {
            // Create a ServiceHost for the PurchaseOrderDLQService type.
            using (ServiceHost serviceHost = new ServiceHost(typeof(PurchaseOrderDLQService)))
            {
                // Open the ServiceHostBase to create listeners and start listening for messages.
                serviceHost.Open();

                // The service can now be accessed.
                Console.WriteLine("The dead letter service is ready.");
                Console.WriteLine("Press <ENTER> to terminate service.");
                Console.WriteLine();
                Console.ReadLine();

                // Close the ServiceHostBase to shutdown the service.
                serviceHost.Close();
            }
        }
    }
}

Imports System
Imports System.ServiceModel.Description
Imports System.Configuration
Imports System.Messaging
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.Transactions

Namespace Microsoft.ServiceModel.Samples
	' Define a service contract. 
	<ServiceContract(Namespace := "http://Microsoft.ServiceModel.Samples")> _
	Public Interface IOrderProcessor
		<OperationContract(IsOneWay := True)> _
		Sub SubmitPurchaseOrder(ByVal po As PurchaseOrder)
	End Interface

	' Service class that implements the service contract.
	' Added code to write output to the console window
	<ServiceBehavior(InstanceContextMode := InstanceContextMode.Single, ConcurrencyMode := ConcurrencyMode.Single, AddressFilterMode := AddressFilterMode.Any)> _
	Public Class PurchaseOrderDLQService
		Implements IOrderProcessor
		Private orderProcessorService As OrderProcessorClient
		Public Sub New()
			orderProcessorService = New OrderProcessorClient("OrderProcessorEndpoint")
		End Sub

		<OperationBehavior(TransactionScopeRequired := True, TransactionAutoComplete := True)> _
		Public Sub SimpleSubmitPurchaseOrder(ByVal po As PurchaseOrder)
			Console.WriteLine("Submitting purchase order did not succeed ", po)
			Dim mqProp As MsmqMessageProperty = TryCast(OperationContext.Current.IncomingMessageProperties(MsmqMessageProperty.Name), MsmqMessageProperty)

			Console.WriteLine("Message Delivery Status: {0} ", mqProp.DeliveryStatus)
			Console.WriteLine("Message Delivery Failure: {0}", mqProp.DeliveryFailure)
			Console.WriteLine()
		End Sub

		<OperationBehavior(TransactionScopeRequired := True, TransactionAutoComplete := True)> _
		Public Sub SubmitPurchaseOrder(ByVal po As PurchaseOrder) Implements IOrderProcessor.SubmitPurchaseOrder
			Console.WriteLine("Submitting purchase order did not succeed ", po)
			Dim mqProp As MsmqMessageProperty = TryCast(OperationContext.Current.IncomingMessageProperties(MsmqMessageProperty.Name), MsmqMessageProperty)

			Console.WriteLine("Message Delivery Status: {0} ", mqProp.DeliveryStatus)
			Console.WriteLine("Message Delivery Failure: {0}", mqProp.DeliveryFailure)
			Console.WriteLine()

			' Resend the message if timed out.
			If mqProp.DeliveryFailure = DeliveryFailure.ReachQueueTimeout OrElse mqProp.DeliveryFailure = DeliveryFailure.ReceiveTimeout Then
				' Re-send.
				Console.WriteLine("Purchase order Time To Live expired")
				Console.WriteLine("Trying to resend the message")

				' Reuse the same transaction used to read the message from dlq to enqueue the message to the application queue.
				orderProcessorService.SubmitPurchaseOrder(po)
				Console.WriteLine("Purchase order resent")
			End If
		End Sub

		' Host the service within this EXE console application.
		Public Shared Sub Main()
			' Create a ServiceHost for the PurchaseOrderDLQService type.
			Using serviceHost As New ServiceHost(GetType(PurchaseOrderDLQService))
				' Open the ServiceHostBase to create listeners and start listening for messages.
				serviceHost.Open()

				' The service can now be accessed.
				Console.WriteLine("The dead letter service is ready.")
				Console.WriteLine("Press <ENTER> to terminate service.")
				Console.WriteLine()
				Console.ReadLine()

				' Close the ServiceHostBase to shutdown the service.
				serviceHost.Close()
			End Using
		End Sub
	End Class
End Namespace

Der folgende Code ist für die Dienstkonfigurationsdatei für die Warteschlange für unzustellbare Nachrichten.The following is code for the dead-letter queue service configuration file.

Siehe auchSee Also

WarteschlangenübersichtQueues Overview
Vorgehensweise: Austauschen von Nachrichten in einer Warteschlange mit WCD-EndpunktenHow to: Exchange Queued Messages with WCF Endpoints
Behandlung nicht verarbeitbarer NachrichtenPoison Message Handling