Abstractに記載したとおり、AD認証のCrmServiceのWebサービスを大量に呼び出すとメッセージが「ErrorCode:10048、Message:通常、各ソケット アドレスに対してプロトコル、ネットワーク アドレス、またはポートのどれか 1 つのみを使用できます。」 となるSocketExceptionが発生します。

AD認証の場合、CrmServiceのExecuteやCreateなどの1回のリクエストが完了すると使用したポートが閉じられ、次のリクエストでは別のポートが使用されます。そのため、短期間(4分位)に大量にWebサービスを呼び出すと使用可能なポートがあっという間になくなってしまい(使用済みポートはTIME_WAITになる)上記例外が発生します。

原因のひとつは、クライアントから任意にポートを開く場合に使用できるポートが1024から5000までであることです。詳細は、下記のKBを参照してください。

5000 を超える番号の TCP ポートから接続しようとすると 'WSAENOBUFS (10055)' エラーが表示される
http://support.microsoft.com/kb/196271/ja

Crmの場合ほかシステムからマスタやアカウント情報を連携する可能性があるため、パフォーマンスを向上させるため、マルチスレッドでCrmServiceを使用しているとTIME_WAITとなったポートが完全に破棄される前にあっという間にポートが枯渇してしまいます。

上記の問題は、AD認証を行う場合に、使用したポートを再利用することで回避できます。

そのためには、次のプロパティをtrueにします。

CrmService.UnsafeAuthenticatedConnectionSharing = true;
CrmService.PreAuthenticate = true;

UnsafeAuthenticatedConnectionSharingのMSDNはこちら
http://msdn.microsoft.com/ja-jp/library/system.web.services.protocols.httpwebclientprotocol.unsafeauthenticatedconnectionsharing.aspx

ポートを1回の呼び出しで破棄しないようにすることで対応します。PreAuthenticateをtrueにすることで、事前に認証を行うのでスループットを向上させています。これはなくてもOKだと思いますが、設定しないとIISのログで何度も認証が行われることが確認できるため、trueのほうがパフォーマンスの向上が望めます。

そのほかの回避方法として、レジストリを修正して、ポートを閉じてから完全に破棄されるまでの時間(既定で4分)を短くしても対応できますが、OSレベルの対応となってしまいます。修正するレジストリは HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay です。

レジストリを修正してTIME_WAITの期間を短くする場合は、次のブログ記事が参考になります。
Only one usage of each socket address (protocol/network address/port) is normally permitted
http://blogs.msdn.com/dgorti/archive/2005/09/18/470766.aspx


MSDNフォーラムに参考になるスレッドがあります
CrmService Exception "Only one usage of each socket address (protocol/network address/port) is normally permitted"
http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/e550295c-83f7-41e3-9453-73c9b87103b6

説明は以上です。

Dynamics CRM 4.0 で問題が発生することと回避できることを確認しています。