2007/08/23(Thu) 20:26:20 編集(投稿者)
■No6784 (JJ さん) に返信
> 今回のアプリではマルチスレッドで
> 同時にということはないので
> 問題ないかと考えております。
それは問題認識が甘いです。
BeginConnectした時点でマルチスレッドです。
Callbackはどんなスレッドで呼ばれるのか、保証がありません。
呼び出し元の場合もあれば、Pooledなスレッドの場合、そうでない他のスレッドの場合もあります。
ですので、Callbackで変数を使うなら、同期機構をいれないとダメです。
> 具体例をあげていただけると大変助かります。
何をしたいのかも明確にわかるので、
私の持ってるソースを見せれば役に立つだろうと思うのですが。
今日はいろいろめんどくさいので、手書き+検証無し+うろ覚えで。
まず、ウェイトだけならCallbackは要りません。
IAsyncResult.AsyncWaitHandleで待てばいいだけです。
AsyncWaitHandleは作成にコストがかかる場合もあるので、
IsCompleteかCompletedSynchronouslyで確認しておくといいです。
BeginXXXを途中で無理やり閉じると例外を吐くものもあるのでそれも処理します。
まとめると。
BeginXXXの一般的タイムアウト指定方法は下記の用になります。
(手書き+検証無し+うろ覚えにつき注意)
IAsyncResult iar = tc.BeginConnect(host, portNo, null, null);
if ( !iar.CompletedSynchronously ) { か if ( !iar.IsCompleted ) {
if ( !iar.WaitOne(timeoutMSec, false) ) {
try {
//ここにCleanupを。
tc.close();
} catch {
}
Throw New TimeoutException();
}
}
tc.EndConnect(iar);
IAsyncResultに関しては「非同期プログラミングのデザインパターン」で検索。
IAsyncResultをきちんと理解しておくと、かなり使えます。