2016-05-18 13 views
1

私はこのようになりますクラスに取り組んでいます:一致が見つかったときイベントをクロススレッドで呼び出す?

public class MatchmakingService { 
    private bool working; 
    private List<MatchmakingUser> matchmakingUsers; 
    // ... 

    public MatchmakingService() 
    { 
     matchmakingUsers = new List<MatchmakingUser>(); 
    } 

    public void StartService() { 
     var thread = new Thread(this.MatchmakingWork); 
     working = true; 
     thread.Start(); 
    } 

    void MatchmakingWork() { 
     while (working) 
     { 
      // some work, match found! 
      { 
        if(onMatchFound != null) 
         onMatchFound(this, new NewMatchEventArgs(matchmakingUsers[i], matchmakingUsers[j]); 
      } 
      Thread.Sleep(1000); 
     } 
    } 
} 

通常、私はちょうどonMatchFoundイベントを起動したいと毎日それを呼び出すが、サービスのスレッドがあるので、このイベントのサブスクライバは別のスレッドになります - それをどう対処するのですか?私はそれをするのは安全ではないと、それが本当であれば私の選択肢は何かを読んだことがありますか?

注:私はWinFormsで作業していないので、ControlのInvoke Shenanigansはありません。

+0

これは状況によって異なります。イベントのサブスクライバが別のスレッドにあるときは、それだけで何も問題はありません(特に、UIプラットフォームになく、UIスレッドに何もディスパッチする必要がない場合)。 – Evk

答えて

2

最も簡単な方法は、キューを作成することです。キューを実装する方法は複数あります。 MatchmakingService

キューを使用して一致を保存し、もう1つのスレッドはRaiseEvents()メソッドを呼び出してキューを処理する必要があります。これは、意味他のスレッドがタイマ/ DispatcherTimerを持つ必要があります/スリープなどとしながら...

例:

public class MatchmakingService 
{ 
    private bool working; 
    private List<MatchmakingUser> matchmakingUsers; 
    // ... 

    // the queue 
    private List<NewMatchEventArgs> _queue = new List<NewMatchEventArgs>(); 


    public MatchmakingService() 
    { 
     matchmakingUsers = new List<MatchmakingUser>(); 
    } 

    public void StartService() 
    { 
     var thread = new Thread(this.MatchmakingWork); 
     working = true; 
     thread.Start(); 
    } 

    void MatchmakingWork() 
    { 
     while (working) 
     { 
      // some work, match found! 
      { 
       lock (_queue) 
        _queue.Add(new NewMatchEventArgs(matchmakingUsers[1], matchmakingUsers[2])); 
      } 
      Thread.Sleep(1000); 
     } 
    } 

    public void RaiseEvents() 
    { 
     NewMatchEventArgs[] copyOfQueue; 

     // create a copy (bulk action) 
     lock (_queue) 
     { 
      copyOfQueue = _queue.ToArray(); 
      _queue.Clear(); 
     } 

     // handle the items 
     if (onMatchFound != null) 
      foreach (var item in copyOfQueue) 
       onMatchFound(this, item); // indices are examples 

    } 

    public event EventHandler<NewMatchEventArgs> onMatchFound; 

} 
+0

ええ、私はすでに要求のためのキューを持っていたので、これは良いよ、ありがとう! – user1255410

+0

特に '//コピーを作成する(バルクアクション)'は非常に便利です。キューのコピーを作成し、作業スレッドのキューを解放します。これは、一括処理の処理にも役立ちます。 TCP/IPなどからのメッセージやその他の非同期のもの(Invoke/Dispatcherなどが利用できない場合) –

関連する問題