.configファイルに基づいてServiceHostsを動的に作成する小さなWCFホスティングエンジンを作成しています。一般的な考え方は、すべてのサービスをオフラインにすることなく、実行時に既存のサービスを削除したり、新しいサービスを追加したりできるようにすることです。
問題のあるユニットテストに遭遇しました。これは、これが思ったほど簡単ではない可能性があることを示しています。特定のエンドポイントには1つのServiceHostしか存在しないようです(サービスの複数の異なるエンドポイントが1つのServiceHostに存在する場合でも)。これは通常は問題ではありませんが、サービスを再構成する必要がある場合、元のServiceHostを停止しても、実際にはそのエンドポイントアドレスの登録が強制終了されることはありません。同じサービス(つまり、同じエンドポイントが使用されている)に対して別のServiceHostを作成しようとすると、次の例外が発生して失敗します。
System.InvalidOperationException: The ChannelDispatcher at 'net.pipe://localhost/' with contract(s) '"ITestService"' is unable to open its IChannelListener. --->
System.InvalidOperationException: A registration already exists for URI 'net.pipe://localhost/'.
ユニットテスト中に実際にエラーが発生しています。テストでは1つのユニットを実行します。これにより、ServiceHostsとホスティングエンジンが人間的に可能な限り完全にシャットダウンされます。次に、ホスティングエンジンの別のインスタンスを作成します。このインスタンスは、別のテストのために同じServiceHostsを再作成しようとします。2番目のテストでは、上記のエラーが発生します。ServiceHost.Close()が呼び出されている間、それは実際にはサービスホストを破棄しないと推測しています...したがって、それはまだメモリ内でぶら下がっています。GCが古いサービスホストをクリーンアップしているかどうかはわかりません...問題は最初に発生した後も解消されずに解決しません(私が判断できたのは最善です...これまで約30分待っていました。 )。
system.serviceModelの構成ファイルは次のとおりです。
<system.serviceModel>
<services>
<service name="Campus.Core.ServiceModel.TestServiceStub">
<endpoint
address="net.pipe://localhost"
binding="netNamedPipeBinding"
contract="Campus.Core.ServiceModel.ITestService"
/>
</service>
</services>
</system.serviceModel>