2012-01-17 17 views
0

WCFサービスhereでトランザクションを説明しているMSDNのページに出くわしました。私はバインディングの設定を微調整し、netTcpBindingを使用しました。ここに私のapp.configファイルのserviceModelセクションは次のとおりです。クライアントとWCFサービスの間のnetTcpBindingとの1つの接続がある

<system.serviceModel> 
<bindings> 
    <netTcpBinding> 
    <binding name="netTcpBindingConfiguration1" transactionFlow="true"> 
     <security mode="Message" /> 
    </binding> 
    </netTcpBinding> 
</bindings> 
<services> 
    <service name="OrderingService.OrderService"> 
    <clear /> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" 
     listenUriMode="Explicit"> 
    </endpoint> 
    <endpoint address="net.tcp://localhost:8880/OrderingService" 
     binding="netTcpBinding" bindingConfiguration="netTcpBindingConfiguration1" 
     contract="OrderingService.IOrderService" /> 
    <host> 
     <baseAddresses> 
     <add baseAddress="http://localhost:8888/OrderingService/" /> 
     </baseAddresses> 
    </host> 
    </service> 
</services> 
<behaviors> 
    <serviceBehaviors> 
    <behavior> 
     <serviceMetadata httpGetEnabled="True" /> 
     <serviceDebug includeExceptionDetailInFaults="False" /> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 

私はサービスのクライアントとしてWindowsアプリケーションを作成しました。 netstatコマンドを使用して、クライアントとサービス(コンソールアプリケーションでホストされている)間のTCP接続を確認しました。私は各操作(サービスのプロキシクラスのメソッドを呼び出すことによって新しいオーダーを行うクライアントアプリケーションのボタンをクリックしていた)を認識し、新しい接続が作成され、以前の接続はすべて確立されたままです。明らかに、これは理想的な条件ではありません。私は何が間違っていたのか、接続の数を1つに減らしてこの問題を解決する設定や構成があるのか​​疑問に思いました。ちなみに、サービスインターフェイスを実装するサービスクラスは、InstanceContextModeがPerSessionに設定されています。ここでは、契約のインターフェースとサービスクラスは以下のとおりです。

[ServiceContract(SessionMode=SessionMode.Required)] 
public interface IOrderService 
{ 
    [OperationContract] 
    [TransactionFlow(TransactionFlowOption.NotAllowed)] 
    List<Customer> GetCustomers(); 

    [OperationContract] 
    [TransactionFlow(TransactionFlowOption.NotAllowed)] 
    List<Product> GetProducts(); 

    [OperationContract] 
    [TransactionFlow(TransactionFlowOption.Mandatory)] 
    string PlaceOrder(Order order); 

    [OperationContract] 
    [TransactionFlow(TransactionFlowOption.Mandatory)] 
    string AdjustInventory(int productId, int quantity); 

    [OperationContract] 
    [TransactionFlow(TransactionFlowOption.Mandatory)] 
    string AdjustBalance(int customerId, decimal amount); 
} 

[ServiceBehavior(TransactionIsolationLevel = IsolationLevel.Serializable, 
    TransactionTimeout = "00:00:20", 
    InstanceContextMode = InstanceContextMode.PerSession, 
    TransactionAutoCompleteOnSessionClose = true)] 
public class OrderService : IOrderService 
{...} 

ここでインクルードは、クライアントアプリでプロキシクラスを使用するコードは次のとおりです。

using (TransactionScope scope = new TransactionScope()) 
     { 
      try 
      { 
       proxy = new OrderServiceClient("NetTcpBinding_IOrderService"); 
       result = proxy.PlaceOrder(order); 
       MessageBox.Show(result); 

       result = proxy.AdjustInventory(product.ProductId, quantity); 
       MessageBox.Show(result); 

       result = proxy.AdjustBalance(customer.CustomerId, product.Price * quantity); 
       MessageBox.Show(result); 
       proxy.Close(); 
       scope.Complete(); 
      } 
      catch (Exception exc) 
      { 
       MessageBox.Show("Error occurred: " + exc.Message); 
      } 
     } 

答えて

0

ESTABLISHED残りのTCPコネクションに関しては - あなたが呼んでいます終了したらクライアントのインスタンスで.Close()を実行しますか?

単一の接続を使用する場合は、インスタンスコンテキストモードを「シングル」に変更し、クライアントで確立した接続を再利用してすべてのサービスコールを処理する必要があります。これは、サービス内の状態を維持したいアーキテクチャに適しています。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
public class Service : IService 
{ 
} 

私はWCFのコンテキストモードについて学んでいたとき、私は非常に役立つ、このリンクを見つけた:あなたが現在PerSessionコンテキストモードを使用しているとして、あなたが追加することによって、単一の接続に制限することができるはずCodeProject link

ビヘイビアセクションのmaxConcurrentSessionsに設定します。

<serviceBehaviors> 
    <behavior> 
     <serviceMetadata httpGetEnabled="True" /> 
     <serviceDebug includeExceptionDetailInFaults="False" /> 
     <serviceThrottling maxConcurrentSessions="1" /> 
    </behavior> 
    </serviceBehaviors> 

これは、単一のクライアントがある場合にのみ有効です。

+0

はい。質問を編集し、クライアントアプリケーションでプロキシクラスを使用するコードを追加しました。 – user1137993

+0

私は私の答えに追加しました。 – alundy

+0

ヒントをありがとう!私は問題を解決しました。問題は各呼び出しの後で、私はプロキシオブジェクトを閉じました。 – user1137993

関連する問題