2016-05-18 1 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); 
    } 
} 

Теперь я беспокоюсь о matchmakingUsers список, так что я понял, я бы просто назвать это AddMatchmakingUser для выполнения в этом потоке службы, но не действительно умею. Я читал о классе Dispatcher, но у mono в Unity нет его или это совсем другая технология. В основном я хотел бы сделать:

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

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

ответ

0

Просто позвоните AddMatchmakingUser из любого потока и синхронизировать весь код, который экранный список, чтобы предотвратить их от происходящего в то же время и вызывает состояние гонки:

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

Выполняйте то же самое внутри MatchmakingWork всякий раз, когда вы получаете доступ к списку.

+0

matchmakingUsers будут использоваться для сложных операций в их рабочем потоке, я не могу заблокировать риск слишком много времени, потраченного на ожидание его освобождения. – user1255410

+0

Поскольку большую часть времени поток 'MatchmakingWork' является единственным, кто работает со списком, ждать не будет. Ожидание произойдет только после изменения из списка. Я предполагаю, что это должно быть редким явлением. Если блокировка каждого доступа к списку индивидуально по-прежнему создает проблему с производительностью, вы можете заблокировать более крупный блок кода, например. даже полная итерация цикла. Недостатком будет то, что код вызова должен будет дождаться завершения этого процесса, прежде чем он сможет изменить список (что может быть хорошей идеей, тем не менее, ради последовательности). –

+1

В качестве альтернативы вы можете добавить дополнительных пользователей в отдельный 'ConcurrentQueue' при вызове' AddMatchmakingUser' и обработать эту очередь в начале каждой итерации в 'MatchmakingWork', т. Е. Переместить их в фактический список, который вы обрабатываете. Таким образом вам вообще не понадобится блокировка. –

Смежные вопросы