2009-02-26 18 views
0

私は困惑しているアプリケーションで何か変わった動作をしています。スレッドプール用に標準スレッドを再利用できますか?

は、私がスレッドを作成、のは、通信要求を処理する責任がある労働者、それを呼びましょう。スレッドが要求を消費してメッセージを送信している間、クライアントはパイプに書き込みます。

は今、スレッドのメインループは、このような何かを持っています

lock(this) 
{ 
    object_id = Transport.BeginSend(xxx, xxx, callback, yyy) 
    clientsObjects[object_id] = client_id; 
} 

今のコールバックは、私が書いたものよりも、その少し複雑(CLIENT_IDにアクセスする必要があるが、事はそのコールバックですOBJECT_IDを受け、ちょうどコールバックはclientsObjects[object_id] = client_id;が実行できる前に、それが実際に起こることを非常に速く射撃可能性があるためBeginSendがUdpClient.BeginSend

void Callback(IAsyncResult ar) 
{ 
    State st = (State)ar; 
    lock(this) 
    { 
    client_id = clientsObjects[st.object_id] 
    } 
} 

ロックへの呼び出しがあると仮定している...

今、問題はそれが機能していないことです。うまくいきました。 BeginSendを実行しているスレッドのManagedThreadIdsとコールバックを実行しているスレッドのManagedThreadIdsをトレースすると、時には同じThreadIdがあることがわかります!!

これは可能ですか?それはどうしたらできますか?私は何が間違っているのかについての示唆は何ですか?

コメント:トランスポートはトランスポート層を簡単に変更できるUDPClientのラッパーです。ロックは実際にはロックではなくスピンロックです。書き留めました。

答えて

1

Hereはない非同期あなたが期待するように、実際に同期して動作するStream.BeginRead()関数について語っ古い記事です。この記事は2004年のものなので、.NET 1.0/1.1を指していると仮定しています。この記事では特にUdpClient.BeginSend()を参照していませんが、SocketのBeginXXX関数が同じ動作をしているかどうか、特にすぐに読み取られるデータがあるかどうか不思議でした。これが可能かどうかを確認するには、Webをチェックする価値があります。

それはBeginSend()関数の状態パラメータを経由してコールバック関数へのclient_idを渡すことは可能ですか?

object_id = Transport.BeginSend(xxx, xxx, Callback, client_id); 
+0

アメージング、確かに時々非同期呼び出しは同期になり...何混乱! –

関連する問題