2 つの例に関する基本コードは次のとおりです。
private void AsyncTest()
{
//GetServiceObject Will add custom bindings and more..
Client client = ClientBuilder.GetServiceObject();
while (true)
{
Semaphore semaphore = new Semaphore(0,1);
client.BeginTest(BeginTestCallback, new AsyncState
{
Client = client,
Semaphore = semaphore
});
semaphore.WaitOne();
}
}
private void BeginTestCallback(IAsyncResult asyncResult)
{
try
{
AsyncState state = asyncResult.AsyncState as AsyncState;
Client client = state.Client;
Semaphore semaphore = state.Semaphore;
Client.EndTest(asyncResult);
semaphore.Release();
}
catch (Exception e)
{
//Will catch the exception here because of Client.EndTest(asyncResult) in the first example
Debug.Assert(false, e.Message);
}
}
コールバックが .net Threadpool のスレッド内で呼び出されることがわかっています。
このように AsyncTest() を呼び出すと:
Task.Factory.StartNew(() => AsyncTest());
これは、AsyncTest が .net Threadpool のスレッドで実行されることを意味します。この場合、すべてが例外なく期待どおりに機能します。
ただし、この方法でスレッドを開始すると:
ThreadStart ts = new ThreadStart(() => AsyncTest());
Thread t = new Thread(ts);
t.Start();
10分に置いても、「SendTimeout」でランダムなTimeoutExceptionが発生します。Wireshark を確認すると、Syn が表示されない状態から、SOAP ヘッダーのみを送信して接続を閉じるまで (タイムアウトした場合のみ) にランダムに移行します。
1 秒あたり 30 のリクエストを実行する 10 のスレッドを実行していることに注意してください。2 番目の例では、失敗するまでに最大 1 分かかる場合があります。
なんで?