共用方式為


HOW TO:與 WCF 端點交換佇列訊息

佇列可確保用戶端與 Windows Communication Foundation (WCF) 服務之間發生可靠的傳訊,即使服務在通訊時無法使用也一樣。 下列程序顯示如何在實作 WCF 服務時,使用標準佇列繫結確保在用戶端與服務間建立永久性通訊。

此章節解釋如何在 WCF 用戶端與 WCF 服務之間使用 NetMsmqBinding 處理佇列通訊。

若要在 WCF 服務中使用佇列

  1. 使用以 ServiceContractAttribute 標記的介面定義服務合約。 在屬於服務合約部分的介面中標示作業為 OperationContractAttribute 並指定它們為單向,因為此方法不用傳回任何回應。 下列程式碼提供範例服務合約以及其作業定義。

    <ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
    Public Interface IOrderProcessor
        <OperationContract(IsOneWay := True)> _
        Sub SubmitPurchaseOrder(ByVal po As PurchaseOrder)
    End Interface
    
    [ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
    public interface IOrderProcessor
    {
        [OperationContract(IsOneWay = true)]
        void SubmitPurchaseOrder(PurchaseOrder po);
    }
    
  2. 當服務合約通過使用者定義型別,您必須為這些型別定義資料合約。 下列程式碼示範兩份資料合約:PurchaseOrderPurchaseOrderLineItem。 這兩個型別定義了傳送至服務的資料 (請注意,定義這類資料合約的類別也定義許多方法。 這些方法不被視為資料合約的部分。 只有以 DataMember 屬性宣告的成員才屬於資料合約的部分)。

    <DataContract(Namespace := "http://Microsoft.ServiceModel.Samples")> _
    Public Class PurchaseOrder
        Private Shared ReadOnly OrderStates() As String = { "Pending", "Processed", "Shipped" }
        Private Shared statusIndexer As New Random(137)
    
        <DataMember> _
        Public PONumber As String
    
        <DataMember> _
        Public CustomerId As String
    
        <DataMember> _
        Public orderLineItems() As PurchaseOrderLineItem
    
        Public ReadOnly Property TotalCost() As Single
            Get
                Dim totalCost_Renamed As Single = 0
                For Each lineItem In orderLineItems
                    totalCost_Renamed += lineItem.TotalCost
                Next lineItem
                Return totalCost_Renamed
            End Get
        End Property
    
        Public ReadOnly Property Status() As String
            Get
                Return OrderStates(statusIndexer.Next(3))
            End Get
        End Property
    
        Public Overrides Function ToString() As String
            Dim strbuf As New System.Text.StringBuilder("Purchase Order: " & PONumber & Constants.vbLf)
            strbuf.Append(Constants.vbTab & "Customer: " & CustomerId & Constants.vbLf)
            strbuf.Append(Constants.vbTab & "OrderDetails" & Constants.vbLf)
    
            For Each lineItem In orderLineItems
                strbuf.Append(Constants.vbTab + Constants.vbTab + lineItem.ToString())
            Next lineItem
    
            strbuf.Append(Constants.vbTab & "Total cost of this order: $" & TotalCost + Constants.vbLf)
            strbuf.Append(Constants.vbTab & "Order status: " & Status + Constants.vbLf)
            Return strbuf.ToString()
        End Function
    End Class
    
    [DataContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public class PurchaseOrder
    {
        static readonly string[] OrderStates = { "Pending", "Processed", "Shipped" };
        static Random statusIndexer = new Random(137);
    
        [DataMember]
        public string PONumber;
    
        [DataMember]
        public string CustomerId;
    
        [DataMember]
        public PurchaseOrderLineItem[] orderLineItems;
    
        public float TotalCost
        {
            get
            {
                float totalCost = 0;
                foreach (PurchaseOrderLineItem lineItem in orderLineItems)
                    totalCost += lineItem.TotalCost;
                return totalCost;
            }
        }
    
        public string Status
        {
            get 
            {
                return OrderStates[statusIndexer.Next(3)];
            }
        }
    
        public override string ToString()
        {
            System.Text.StringBuilder strbuf = new System.Text.StringBuilder("Purchase Order: " + PONumber + "\n");
            strbuf.Append("\tCustomer: " + CustomerId + "\n");
            strbuf.Append("\tOrderDetails\n");
    
            foreach (PurchaseOrderLineItem lineItem in orderLineItems)
            {
                strbuf.Append("\t\t" + lineItem.ToString());
            }
    
            strbuf.Append("\tTotal cost of this order: $" + TotalCost + "\n");
            strbuf.Append("\tOrder status: " + Status + "\n");
            return strbuf.ToString();
        }
    }
    
  3. 實作位於類別中的介面其所定義的服務合約方法。

    Public Class OrderProcessorService
        Implements IOrderProcessor
        <OperationBehavior(TransactionScopeRequired := True, TransactionAutoComplete := True)> _
        Public Sub SubmitPurchaseOrder(ByVal po As PurchaseOrder) Implements IOrderProcessor.SubmitPurchaseOrder
            Orders.Add(po)
            Console.WriteLine("Processing {0} ", po)
        End Sub
    End Class
    
    public class OrderProcessorService : IOrderProcessor
    {
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void SubmitPurchaseOrder(PurchaseOrder po)
        {
            Orders.Add(po);
            Console.WriteLine("Processing {0} ", po);
        }
    }
    

    請注意,OperationBehaviorAttribute 放置在 SubmitPurchaseOrder 方法上。 其用意是指定必須在交易內呼叫此作業,而且交易會隨著方法完成而自動完成。

  4. 使用 System.Messaging 建立交易式佇列。 您可以選擇使用 Microsoft Message Queuing (MSMQ) Microsoft Management Console (MMC) 建立佇列。 若是這樣,請確定您建立交易式佇列。

    ' Create the transacted MSMQ queue if necessary.
    If (Not MessageQueue.Exists(queueName)) Then
        MessageQueue.Create(queueName, True)
    End If
    
    // Create the transacted MSMQ queue if necessary.
    if (!MessageQueue.Exists(queueName))
        MessageQueue.Create(queueName, true);
    
  5. 在組態中定義指定服務位址的 ServiceEndpoint 並且使用標準的 NetMsmqBinding 繫結。如需有關使用 WCF 組態的 如需詳細資訊,請參閱 Configuring Windows Communication Foundation Applications

    <services>
      <service 
          name="Microsoft.ServiceModel.Samples.OrderProcessorService"
          behaviorConfiguration="CalculatorServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:8000/ServiceModelSamples/service"/>
          </baseAddresses>
        </host>
        <!-- Define NetMsmqEndpoint -->
        <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTransacted"
                  binding="netMsmqBinding"
                  contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
        <!-- the mex endpoint is exposed at https://localhost:8000/ServiceModelSamples/service/mex -->
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    
  6. 使用從佇列讀取訊息並加以處理的 ServiceHost 建立 OrderProcessing 服務的主機。 開啟服務主機來提供服務。 顯示一則訊息,指示使用者按任意鍵終止服務。 呼叫 ReadLine 以等待按鍵動作,隨後關閉服務。

    ' Create a ServiceHost for the OrderProcessorService type.
    Using serviceHost As New ServiceHost(GetType(OrderProcessorService))
        ' Open the ServiceHost to create listeners and start listening for messages.
        serviceHost.Open()
    
        ' The service can now be accessed.
        Console.WriteLine("The service is ready.")
        Console.WriteLine("Press <ENTER> to terminate service.")
        Console.WriteLine()
        Console.ReadLine()
    
        ' Close the ServiceHostB to shutdown the service.
        serviceHost.Close()
    End Using
    
    // Create a ServiceHost for the OrderProcessorService type.
    using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
    {
        // Open the ServiceHost to create listeners and start listening for messages.
        serviceHost.Open();
    
        // The service can now be accessed.
        Console.WriteLine("The service is ready.");
        Console.WriteLine("Press <ENTER> to terminate service.");
        Console.WriteLine();
        Console.ReadLine();
    
        // Close the ServiceHostB to shutdown the service.
        serviceHost.Close();
    }
    

若要建立佇列服務的用戶端

  1. 下列範例示範如何執行裝載應用程式,以及使用 Svcutil.exe 工具建立 WCF 用戶端。

    svcutil https://localhost:8000/ServiceModelSamples/service
    
  2. 在組態中定義 ServiceEndpoint,藉以指定位址並使用標準 NetMsmqBinding 繫結,如下列範例所示。

    <client>
      <!-- Define NetMsmqEndpoint -->
      <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTransacted" 
                binding="netMsmqBinding" 
                contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
    </client>
    
  3. 建立交易範圍以寫入交易式佇列、呼叫 SubmitPurchaseOrder 作業和關閉 WCF 用戶端,如下列範例所示。

    '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
    
    'Closing the client gracefully closes the connection and cleans up resources.
    client.Close()
    
    //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();
    }
    
    //Closing the client gracefully closes the connection and cleans up resources.
    client.Close();
    

範例

以下內容顯示本範例所囊括的服務程式碼、裝載應用程式、App.config 檔案和用戶端程式碼。

' This is the service code
'  Copyright (c) Microsoft Corporation.  All Rights Reserved.

Imports System
Imports System.ServiceModel.Channels
Imports System.Configuration
Imports System.Messaging
Imports System.ServiceModel
Imports System.Transactions
Imports System.Runtime.Serialization
Imports System.Collections.Generic

Namespace Microsoft.ServiceModel.Samples
    ' Define the purchase order line item.
    <DataContract(Namespace := "http://Microsoft.ServiceModel.Samples")> _
    Public Class PurchaseOrderLineItem
        <DataMember> _
        Public ProductId As String

        <DataMember> _
        Public UnitCost As Single

        <DataMember> _
        Public Quantity As Integer

        Public Overrides Function ToString() As String
            Dim displayString As String = "Order LineItem: " & Quantity & " of " & ProductId & " @unit price: $" & UnitCost + Constants.vbLf
            Return displayString
        End Function

        Public ReadOnly Property TotalCost() As Single
            Get
                Return UnitCost * Quantity
            End Get
        End Property
    End Class

    ' Define the purchase order.
    <DataContract(Namespace := "http://Microsoft.ServiceModel.Samples")> _
    Public Class PurchaseOrder
        Private Shared ReadOnly OrderStates() As String = { "Pending", "Processed", "Shipped" }
        Private Shared statusIndexer As New Random(137)

        <DataMember> _
        Public PONumber As String

        <DataMember> _
        Public CustomerId As String

        <DataMember> _
        Public orderLineItems() As PurchaseOrderLineItem

        Public ReadOnly Property TotalCost() As Single
            Get
                Dim totalCost_Renamed As Single = 0
                For Each lineItem In orderLineItems
                    totalCost_Renamed += lineItem.TotalCost
                Next lineItem
                Return totalCost_Renamed
            End Get
        End Property

        Public ReadOnly Property Status() As String
            Get
                Return OrderStates(statusIndexer.Next(3))
            End Get
        End Property

        Public Overrides Function ToString() As String
            Dim strbuf As New System.Text.StringBuilder("Purchase Order: " & PONumber & Constants.vbLf)
            strbuf.Append(Constants.vbTab & "Customer: " & CustomerId & Constants.vbLf)
            strbuf.Append(Constants.vbTab & "OrderDetails" & Constants.vbLf)

            For Each lineItem In orderLineItems
                strbuf.Append(Constants.vbTab + Constants.vbTab + lineItem.ToString())
            Next lineItem

            strbuf.Append(Constants.vbTab & "Total cost of this order: $" & TotalCost + Constants.vbLf)
            strbuf.Append(Constants.vbTab & "Order status: " & Status + Constants.vbLf)
            Return strbuf.ToString()
        End Function
    End Class

    ' Order Processing Logic
    ' Can replace with transaction-aware resource such as SQL or transacted hashtable to hold the purchase orders.
    ' This example uses a non-transactional resource.
    Public Class Orders
        Private Shared purchaseOrders As New Dictionary(Of String, PurchaseOrder)()

        Public Shared Sub Add(ByVal po As PurchaseOrder)
            purchaseOrders.Add(po.PONumber, po)
        End Sub

        Public Shared Function GetOrderStatus(ByVal poNumber As String) As String
            Dim po As PurchaseOrder = Nothing
            If purchaseOrders.TryGetValue(poNumber, po) Then
                Return po.Status
            Else
                Return Nothing
            End If
        End Function

        Public Shared Sub DeleteOrder(ByVal poNumber As String)
            If purchaseOrders(poNumber) IsNot Nothing Then
                purchaseOrders.Remove(poNumber)
            End If
        End Sub
    End Class

    ' 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.
    Public Class OrderProcessorService
        Implements IOrderProcessor
        <OperationBehavior(TransactionScopeRequired := True, TransactionAutoComplete := True)> _
        Public Sub SubmitPurchaseOrder(ByVal po As PurchaseOrder) Implements IOrderProcessor.SubmitPurchaseOrder
            Orders.Add(po)
            Console.WriteLine("Processing {0} ", po)
        End Sub
    End Class
End Namespace
// This is the service code
//  Copyright (c) Microsoft Corporation.  All Rights Reserved.

using System;
using System.ServiceModel.Channels;
using System.Configuration;
using System.Messaging;
using System.ServiceModel;
using System.Transactions;
using System.Runtime.Serialization;
using System.Collections.Generic;

namespace Microsoft.ServiceModel.Samples
{
    // Define the purchase order line item.
    [DataContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public class PurchaseOrderLineItem
    {
        [DataMember]
        public string ProductId;

        [DataMember]
        public float UnitCost;

        [DataMember]
        public int Quantity;

        public override string ToString()
        {
            String displayString = "Order LineItem: " + Quantity + " of "  + ProductId + " @unit price: $" + UnitCost + "\n";
            return displayString;
        }

        public float TotalCost
        {
            get { return UnitCost * Quantity; }
        }
    }

    // Define the purchase order.
    [DataContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public class PurchaseOrder
    {
        static readonly string[] OrderStates = { "Pending", "Processed", "Shipped" };
        static Random statusIndexer = new Random(137);

        [DataMember]
        public string PONumber;

        [DataMember]
        public string CustomerId;

        [DataMember]
        public PurchaseOrderLineItem[] orderLineItems;

        public float TotalCost
        {
            get
            {
                float totalCost = 0;
                foreach (PurchaseOrderLineItem lineItem in orderLineItems)
                    totalCost += lineItem.TotalCost;
                return totalCost;
            }
        }

        public string Status
        {
            get 
            {
                return OrderStates[statusIndexer.Next(3)];
            }
        }

        public override string ToString()
        {
            System.Text.StringBuilder strbuf = new System.Text.StringBuilder("Purchase Order: " + PONumber + "\n");
            strbuf.Append("\tCustomer: " + CustomerId + "\n");
            strbuf.Append("\tOrderDetails\n");

            foreach (PurchaseOrderLineItem lineItem in orderLineItems)
            {
                strbuf.Append("\t\t" + lineItem.ToString());
            }

            strbuf.Append("\tTotal cost of this order: $" + TotalCost + "\n");
            strbuf.Append("\tOrder status: " + Status + "\n");
            return strbuf.ToString();
        }
    }

    // Order Processing Logic
    // Can replace with transaction-aware resource such as SQL or transacted hashtable to hold the purchase orders.
    // This example uses a non-transactional resource.
    public class Orders
    {
        static Dictionary<string, PurchaseOrder> purchaseOrders = new Dictionary<string, PurchaseOrder>();

        public static void Add(PurchaseOrder po)
        {
            purchaseOrders.Add(po.PONumber, po);
        }

        public static string GetOrderStatus(string poNumber)
        {
            PurchaseOrder po;
            if (purchaseOrders.TryGetValue(poNumber, out po))
                return po.Status;
            else
                return null;
        }

        public static void DeleteOrder(string poNumber)
        {
            if(purchaseOrders[poNumber] != null)
                purchaseOrders.Remove(poNumber);
        }
    }

    // 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.
    public class OrderProcessorService : IOrderProcessor
    {
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void SubmitPurchaseOrder(PurchaseOrder po)
        {
            Orders.Add(po);
            Console.WriteLine("Processing {0} ", po);
        }
    }
}
' This is the hosting application.

Imports System
Imports System.ServiceModel.Channels
Imports System.Configuration
Imports System.Messaging
Imports System.ServiceModel
Imports System.Transactions
Imports System.Runtime.Serialization
Imports System.Collections.Generic

Namespace Microsoft.ServiceModel.Samples
    Friend Class hostApp
        ' Host the service within this EXE console application.
        Public Shared Sub Main()
            ' Get MSMQ queue name from appsettings in configuration.
            Dim queueName As String = ConfigurationManager.AppSettings("queueName")

            ' Create the transacted MSMQ queue if necessary.
            If (Not MessageQueue.Exists(queueName)) Then
                MessageQueue.Create(queueName, True)
            End If

            ' Create a ServiceHost for the OrderProcessorService type.
            Using serviceHost As New ServiceHost(GetType(OrderProcessorService))
                ' Open the ServiceHost to create listeners and start listening for messages.
                serviceHost.Open()

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

                ' Close the ServiceHostB to shutdown the service.
                serviceHost.Close()
            End Using
        End Sub
    End Class
End Namespace
// This is the hosting application.

using System;
using System.ServiceModel.Channels;
using System.Configuration;
using System.Messaging;
using System.ServiceModel;
using System.Transactions;
using System.Runtime.Serialization;
using System.Collections.Generic;

namespace Microsoft.ServiceModel.Samples
{
    class hostApp
    {
        // Host the service within this EXE console application.
        public static void Main()
        {
            // Get MSMQ queue name from appsettings in configuration.
            string queueName = ConfigurationManager.AppSettings["queueName"];

            // Create the transacted MSMQ queue if necessary.
            if (!MessageQueue.Exists(queueName))
                MessageQueue.Create(queueName, true);

            // Create a ServiceHost for the OrderProcessorService type.
            using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
            {
                // Open the ServiceHost to create listeners and start listening for messages.
                serviceHost.Open();

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

                // Close the ServiceHostB to shutdown the service.
                serviceHost.Close();
            }
        }
    }
}
<!-- This is the app.config for the service -->
<configuration>

  <appSettings>
    <!-- use appSetting to configure MSMQ queue name -->
    <add key="queueName" value=".\private$\ServiceModelSamplesTransacted" />
  </appSettings>

  <system.serviceModel>
    <services>
      <service 
          name="Microsoft.ServiceModel.Samples.OrderProcessorService"
          behaviorConfiguration="CalculatorServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:8000/ServiceModelSamples/service"/>
          </baseAddresses>
        </host>
        <!-- Define NetMsmqEndpoint -->
        <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTransacted"
                  binding="netMsmqBinding"
                  contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
        <!-- the mex endpoint is exposed at https://localhost:8000/ServiceModelSamples/service/mex -->
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    
    <behaviors>
      <serviceBehaviors>
        <behavior name="CalculatorServiceBehavior">
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

</configuration>
' This is the client code.
'  Copyright (c) Microsoft Corporation.  All Rights Reserved.

Imports System
Imports System.Configuration
Imports System.Messaging
Imports System.ServiceModel
Imports System.Transactions

Namespace Microsoft.ServiceModel.Samples
    'The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.

    'Client implementation code.
    Friend Class Client
        Shared Sub Main()
            ' Create a client.
            Dim client As New OrderProcessorClient()

            ' 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

            'Closing the client gracefully closes the connection and cleans up resources.
            client.Close()

            Console.WriteLine()
            Console.WriteLine("Press <ENTER> to terminate client.")
            Console.ReadLine()
        End Sub
    End Class
End Namespace
// This is the client code.
//  Copyright (c) Microsoft Corporation.  All Rights Reserved.

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

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

    //Client implementation code.
    class Client
    {
        static void Main()
        {
            // Create a client.
            OrderProcessorClient client = new OrderProcessorClient();

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

            //Closing the client gracefully closes the connection and cleans up resources.
            client.Close();

            Console.WriteLine();
            Console.WriteLine("Press <ENTER> to terminate client.");
            Console.ReadLine();
        }
    }
}
<!-- This is the app.config for the client app -->
<configuration>
  <system.serviceModel>
    <client>
      <!-- Define NetMsmqEndpoint -->
      <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTransacted" 
                binding="netMsmqBinding" 
                contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
    </client>
  </system.serviceModel>
</configuration>

另請參閱

工作

交易 MSMQ 繫結
HOW TO:與 WCF 端點和訊息佇列應用程式交換訊息
Windows Communication Foundation 至訊息佇列
訊息佇列至 Windows Communication Foundation
訊息佇列上的訊息安全性

參考

NetMsmqBinding

概念

WCF 中的佇列
安裝訊息佇列 (MSMQ)

其他資源

Message Queuing Integration Binding Samples