標準スレッドがスレッドプールに再利用することはできますか?
-
09-09-2019 - |
質問
私は私を不可解されたアプリケーションでいくつかの奇妙な行動を抱えています。
私はスレッドを作成、のは、通信要求を処理する責任がある労働者、それを呼びましょう。スレッドが要求を消費し、メッセージを送信しながら、クライアントはパイプに書き込みます。
さて、スレッドのメインループは、このような何かを持っています:
lock(this)
{
object_id = Transport.BeginSend(xxx, xxx, callback, yyy)
clientsObjects[object_id] = client_id;
}
今のコールバックは、私が書いたものよりも、その少し複雑のclient_idを(アクセスする必要があるが、事は、コールバックがOBJECT_IDは、ちょうどBeginSendはUdpClient.BeginSend
の呼び出しであると仮定受けるということです。
void Callback(IAsyncResult ar)
{
State st = (State)ar;
lock(this)
{
client_id = clientsObjects[st.object_id]
}
}
コールバックがとても速くclientsObjects[object_id] = client_id;
を実行する前に...それが実際に起こることを発射する可能性があるため、ロックがあります。
[OK]を、今...問題は、それが働いていないが、うまくそれが今して動作します...なぜ?私はBeginSendを実行しているスレッドのManagedThreadIdsと私は
!!時々、彼らは同じスレッドIDを持っていることがわかり、コールバックを実行しているものをトレースした場合ということは可能ですか?どのようにそれが起こることができますか?私が間違っているのかについての任意の提案ですか?
コメント:実際のコードでは、ロックはロックが、スピンロックではない実際にある...しかし、コンセプト自体は、多かれ少なかれ、私は「何で、交通が簡単にトランスポート層を変更することができますUDPClientのラッパーです、まさにそのようではありません書き留めまします。
解決
ここの会談という古い記事ですStream.BeginRead()関数は、実際にない非同期あなたが期待するように、同期して動作について。記事は2004年からですので、私はそれは.NET 1.0 / 1.1に言及だと仮定しています。ソケットのものでBeginXXX関数が常に同じ動作を持っている場合は、すぐに読み込むべきデータがある場合は特に、物品は、具体的UdpClient.BeginSend()を参照していないが、私はしばしば不思議に思っていました。それは、これは可能性があるかどうかを確認するためにウェブをチェックする価値があるかもしれません。
それはBeginSend()関数の状態パラメータを経由してコールバック関数にCLIENT_IDを渡すことは可能ですか?
object_id = Transport.BeginSend(xxx, xxx, Callback, client_id);