2016-06-15 3 views
0

それは根本的な問題のビットかもしれませんが、私は私のプログラミングは私のコードが構成されてい異なるスレッドから単一ressource(ここではTCPソケット)にアクセス

:-)良い習慣であるとして受け入れられているかどうかを知りたいですac#通信クラスの、基礎となるtcpソケットオブジェクトを使用します。それは、オープン、クローズ、リードおよびライトアクセスをサポートする他のオブジェクトであってもよい。

1つの通信は、電文の送信と相手側からの応答を待ちます。

これまでは、このクラスには1つのスレッド内からしかアクセスしませんでした。それはうまくいった。今日私は、フォームクラスから作成され、フォームクラスから開始された2つのパラレル作業スレッドを使用してテストしました。通信オブジェクトはフォームクラスのオブジェクトでした。スレッド(単にフォームクラスのメソッド)は、いつでも通信オブジェクトにアクセスできます。

しかし、残念なことに、ロックされていないため、あるスレッドが別のスレッドの応答電文を受信する可能性があります。

public Boolean Read(UInt16 adress,out UInt16 value) 
{ 
    lock(this) 
    { 
     // send the read telegram and receive 
     // an ACK Telegram with the data 
     value = _connection.Read(adress); 
    } 
} 

public Boolean Write(UInt16 adress,UInt16 value) 
{ 
    lock(this) 
    { 
     // send the Write telegram and receive 
     // an ACK Telegram with the data 
     return _connection.Write(adress,value); 
    } 
} 

この例のコードは、実際のコードに似ているdoesntのが、ロックは、()は興味深いものです: は、これを解決するために、私は単にロックの内側(){}文をすべての私の呼び出し機能を置きます。 私の質問は次のとおりです:

  • ロック機構は十分ですか?
  • ロックを入力するために多くのスレッドが待機している場合は、待機中のすべてのスレッドにアクセスすることが保証されていますか?そしてそのような問題では、より高速のスレッドでさえ、より遅いスレッドをブロックしないのですか?
  • スレッドが次々にオブジェクトにアクセスできるように、何らかの種類のスケジューラをプログラムするのが現実的でしょうか?

[#1をコメントする答えとして編集]
複雑にその全てが投稿するので、私は、より詳細なソースコードを与えることができない - プロトコルの詳細、ソケットカプセル化し、すべてのそれらの事のために複数のオブジェクトを。

  • 私のメソッドはすべて、ソケットへの同期呼び出しを使用します。
  • すべてのメソッドはデータ(テレグラム)を送信し、完全な応答電文が得られるかソケットがタイムアウトするまで待機します。

あなたはキューイングについて何か書きました。私はこれを考慮しませんでした。しかし、IIRCの私の図書館(2000年以前の古き良きC++コード)は、COM/DCOM通信でこの問題を解決するために何らかのキューイングを行っていました。

おそらく私はこのコードをもう一度見てください。 クラスオブジェクトに対するマルチスレッド通信の私の他の解決策は、同時に複数のクラスオブジェクトを使用することです。各スレッドは独自のソケット接続を使用し、何も混在しません。

一方、相手側のターゲットサーバは、マルチスレッド方式を使用して各ソケット接続を処理し、ロック機構(Mutexes)と同期(Events)を使用してパラレルテレグラムをシリアルにキューイングしますサーバーのキュー。

[編集#2]
は異なる方法でロック(これは)リードを()最初のスレッドが書き込みを呼び出している間に()を呼び出すために、他のスレッドを防ぐいますか?

+1

キューイング技術について調べましたか? –

+0

@CamBruceと同じです。ソケット(またはその他)からマルチスレッドを読み書きすることは決してありません。どのスレッドがメッセージを受信したかをスレッドはどのように知っていますか?送信時に、別のスレッドからメッセージを送信するときに、メッセージを混在させたくありません。 Threadsafetyは、すべてをロック内に置くことで完全に修正することはできません。あなたが提供していること、何を、どのように実装しているのか。必要に応じて代替案を提示するかもしれませんが、 –

答えて

0

私は私のコードで別のテストを経て、そして

lock(this) 
{} 

の使用について何も悪いしかし、複数のスレッドからソケットの読み取り/書き込みするのは本当に良くない習慣がないように思えます。 ので、私は場所に両方のロックを持っているだろうと思う:

  • ロック(この){}
  • はコンストラクタで使用したものに対してThread.CurrentThread.ManagedThreadIdチェック。

最初のものは、同じスレッドが同時に2つの異なるメソッド(通常のプログラムフローに1つと、invoke-patternsで使用するときに1つ)を入力しないようにします。

関連する問題