2014-11-20 4 views
0

У меня есть список, связанный с коллекцией.Wpf Dispatcher Pause and Continue

Коллекция обновляется с помощью диспетчера dispatcher.current, так что элементы постепенно добавляются в представление списка.

Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => 
{ 
     if(continueDispatcher)numDone = DoStuff(); 
})); 

Это работает очень хорошо, и флаг continueDispatcher останавливает поток в самом зародыше, это круто, но я хотел бы, чтобы иметь возможность продолжать диспетчерские операции на кнопку мыши.

Я прочитал о рамах диспетчера и т.п., но я, похоже, не могу найти решение, которое работает.

У кого-нибудь есть идеи по этому вопросу?

Edit - Подробнее Код

//for each image 
foreach (var result in results) 
{ 
    result.Type = type; 

    numDone = LoadImagesAsync(result, numDone, total); 
} 

private int LoadImagesAsync(Item result, int numDone, int total) 
{ 
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => 
    { 
     //keep looping 
     while (true) 
     { 
      //if the dispatcher is paused then continue the loop 
      if (DispatcherPaused) continue; 

      //if the dispatcher is not paused then perform the action and break out of the loop 
      numDone = DoStuff(result, numDone, total); 
      break; 
     } 
    })); 
    return numDone; 
} 

private int DoStuff(Item result, int numDone, int total) 
{ 
    ItemList.Add(result); 
    numDone++; 
    ProgressBarValue = ((double) numDone/total)*100; 
    return numDone; 
} 
  • C#
  • Visual Studio 2012
+0

Извините, я просто не понимаю, что вы пытаетесь сделать. И как этот флаг * останавливает поток, мертвый на своих дорожках *? – Dirk

+0

Почему бы не положить его в бесконечный цикл? например 'while (true) {if (continueDispatcher) numDone = DoStuff();}' – Bijan

+0

@Bizz Это работает, но он блокирует пользовательский интерфейс при запуске цикла. –

ответ

1
Thread t = new Thread(() => 
{ 
    while (true) 
    { 
     if (continueDispatcher) 
      numDone = DoStuff(); 
     Thread.Sleep(50); 
    } 
}); 
t.Start(); 
+1

'Application.DoEvents' - это API Windows Forms. Он не заставит диспетчера обрабатывать свою очередь, и даже если вы переопределите его для WPF, это все равно анти-шаблон. –

+0

@Mike вы правы, я удалил свой первый метод – Bijan

1

Во-первых, вы должны никогда блок/монополизировать поток пользовательского интерфейса, как это , Найдите другой способ управления долговременной и прерывистой задачей. Если возможно, используйте BackgroundWorker и выполняйте основную часть работы над другим потоком, а затем отправляйте обратно в поток пользовательского интерфейса, чтобы сообщать о достигнутых результатах и ​​фиксировать свои результаты (либо немного за раз, либо сразу).

Кроме того, если вы хотите «приостановить» операцию, вы не должны просто оживлять в цикле. Это приведет к загрузке вашего процессора через крышу. В общем, вы должны использовать какой-то дескриптор ожидания, чтобы отправить поток в состояние ожидания, пока вы не уведомите его о возобновлении (но никогда не делайте этого с потоком пользовательского интерфейса).

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