2016-05-18 5 views
0

私はこのようになりますクラスに取り組んでいます:別のスレッドで動作するクラスの関数をどのように呼び出すのですか?

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 
      Thread.Sleep(1000); 
     } 
    } 

    // ... 
    public void AddMatchmakingUser(MatchmakingUser user) 
    { 
     matchmakingUsers.Add(user); 
    } 
} 

は今、私はので、私は、私はちょうどこのサービスのスレッドで実行するために、このAddMatchmakingUserを呼びたい考え出しmatchmakingUsersリスト心配だけど、しないでください本当に知っている方法。私はDispatcherクラスについて読んだことがありますが、Unityのモノはそれを持っていないか、まったく別のテクノロジーです。基本的に私はやってみたい:

MatchmakingService mmService = new MatchmakingService(); 
mmService.Start(); 

// sometime later when needed 
mmService.Somehowinvokeinworkingthread(mmService.AddMatchMakingUser(...)); 

答えて

0

はただのスレッドからAddMatchmakingUserを呼び出すと同時に、occuringと競合状態を引き起こしてからそれらを防ぐために、リストをaccesingだすべてのコードを同期:

public void AddMatchmakingUser(MatchmakingUser user) 
{ 
    lock (matchmakingUsers) 
    { 
     matchmakingUsers.Add(user); 
    } 
} 

リストにアクセスしているときはいつも、MatchmakingWorkと同じにしてください。

+0

matchmakingUsersは動作中のスレッドで複雑な操作に使用されますが、ロックを解除するのに時間がかかりすぎることはありません – user1255410

+0

ほとんどの場合、 'MatchmakingWork'スレッドだけが動作している限りリストでは、待つことはありません。待機は、リストから変更するときにのみ発生します。私はこれがまれであるはずだと思います。すべてのリストアクセスを個別にロックすると、パフォーマンス上の問題が発生する場合は、より大きなコードブロックをロックすることができます。完全なループ反復でさえも。欠点は、リストを変更する前に、呼び出しコードがこれを完了するのを待たなければならないことです(これは、一貫性のためには良い考えかもしれません)。 –

+1

また、 'AddMatchmakingUser'を呼び出すときに別の' ConcurrentQueue'に追加のユーザを置いて、 'MatchmakingWork'の各繰り返しの始めにそのキューを処理することができます。つまり、処理中の実際のリストに移動させることができます。この方法では、まったくロックする必要はありません。 –