2016-04-11 3 views
0

Это может быть немного сложно объяснить, но я сделаю все возможное.диспетчер не запускается правильно: Application.Current.Dispatcher.Invoke

Окружающая среда - приложение WPF MVVM.

Один из класса включает в себя: ...

public ObservableCollection<Rat> Rats { get; set; } 

...

public void UpdateRats(int nbRats) 
     { 
      try 
      { 
       if (nbRats > 0) 
       { 
        for (int i = 0; i < nbRats; i++) 
        { 
         Application.Current.Dispatcher.Invoke(() => Rats.Add(new Rat())); 
         // Application.Current.Dispatcher.BeginInvoke( new Action(() => Rats.Add(new Rat() ))); 
         // Rats.Add(new Rat()); 
        } 
       } 
       if (threadSimul != null && !threadSimul.IsAlive) 
       { 
        threadSimul = new Thread(new ThreadStart(simul)); 
        threadSimul.Start(); 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 

Когда UpdateRats вызывается потоком, который создал этот объект, все работает отлично. Когда он вызывается из другого потока, выполнение, похоже, останавливается при вызове диспетчера: Application.Current.Dispatcher.Invoke (() => Rats.Add (new Rat()));

Отладчик прекращает показывать активность в этой ветке, хотя пошаговое отладка не показывает доказательств того, что она выходит из потока. Нить, где все еще жив, но я не вижу в этом ничего.

Могу ли я вызвать диспетчера неправильно?

Есть ли причина?

Если это уместно, второй поток создается таким образом:

threadSimul = new Thread(() => simul()); 
      threadSimul.SetApartmentState(ApartmentState.STA); 
      threadSimul.Start(); 

и Simul содержит:

... 
    UpdateRats(n); 
... 

Thx заранее.

ответ

0

Раньше я сталкивался с подобным вопросом. Обычно, создавая диспетчер вне вашего метода, он работает. Попробуйте создать его в своем конструкторе. Что-то вроде:

private Dispatcher _dispatcher; 

public class RatManager() 
{ 
    _dispatcher = Dispatcher.CurrentDispatcher; 
} 

BTW, я бы не вызвал метод Dispatcher.Invoke каждый раз, когда вы делаете цикл. Это выглядело бы лучше (по крайней мере для меня)

// Assuming you already created a Dispatcher variable 
_dispatcher.BeginInvoke(() => 
{ 
    // Loop here 
} 

Обратите внимание, что я использую BeginInvoke здесь. Если вам не нужна операция, выполняемая синхронно, BeginInvoke всегда лучше, потому что она не блокирует поток пользовательского интерфейса

+0

Тот же результат с вашим предложением. Thx в любом случае. –

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