2012-01-25 5 views
1

おはようございます。 この単純なシナリオを考えてみましょう:私はNetClientを持っています。これは、voidメソッドConnect()を使って、リモートサーバーに接続しています。完了すると、NetClientはConnectedイベントを発生します。イベントを発生させ、イベント引数を返すvoidメソッドを同期化させます

私はこのような非同期ロジックを管理することはできません別の呼び出し側にこのNetClientをラップする必要があります。この呼び出し側はOK(簡単にするためには、今の接続エラーについて考えていない)場合はtrueを返し同期Connect()方法を望んでいます。

次のようなコードを見て:


    public class Client 
    { 
     NetClient m_NetClient = new NetClient(); 

     public void Connect(string ip, int port) 
     { 
      m_NetClient = new NetClient(); 
      m_NetClient.Connected += _NetClient_Connected; 
      m_NetClient.Connect(ip, port); 
     } 

     private void _NetClient_Connected(object sender, EventArgs e) 
     { 
      //... 
     } 
    } 

が、私はこのロジックの同期を行うために何ができますか? Monitorクラスのようなものを使うよりも、イベントハンドラの新しいスレッドを立ち上げる必要がありますか? 誰かがこの目標を達成するために自分のopionin/codeを教えてもらえますか?

ありがとうございました!

答えて

1

AutoResetEventはすべきことです。

必要にOK
public class Client 
     { 
      NetClient m_NetClient = new NetClient(); 
      AutoResetEvent _lock = new AutoResetEvent(false); 
      bool result; 

      public bool Connect(string ip, int port) 
      { 
       m_NetClient = new NetClient(); 
       m_NetClient.Connected += _NetClient_Connected; 
       m_NetClient.Connect(ip, port); 
       _lock.WaitOne();//wait for thread to finish 
       return result; 
      } 

      private void _NetClient_Connected(object sender, EventArgs e) 
      { 
       //... 
       result = e.Result; 
       _lock.Set(); //inform waiters 
      } 
     } 
+0

ありがとうございます。 Monitor.Wait e Monitor.Pulseを使ってみましたが、Connect()で新しいスレッドを作成していました。 私もあなたのソリューションを試してみます、ありがとう! Nando –

1

  1. プライベートメンバ
  2. としてAutoResetEventの定義が_NetClient_ConnectedコールSet()
0123で m_NetClient.Connect(ip, port);コール WaitOne()
  • Connect
  • でそれを初期化

    あなたは注意する必要がありますどのようなNOTE

    は永遠にあなたのコードをロックしないことですので、あなたは、例外を処理し、同様にそれらの例でSet()を呼び出す必要があります。 の場合は、タイムアウトを指定してWaitOneを呼び出して、タイムアウト後にロックが解除されるようにしてください。

  • +0

    コメントありがとうございます、あなたは正しい:デッドロックは常にコーナーの後ろにあります:) –

    関連する問題