2010-11-26 2 views
0

У меня есть класс, написанный на C#. В нем я хочу запустить определенную функцию параллельно в списке. После завершения каждого элемента я хотел бы обновить индикатор выполнения. Однако из моей программы я получаю очень странное поведение. Он выполняет это событие и доходит до моего юнита, но никогда не выполняет фактически никакого кода. Вместо этого он просто замерзает. (Я смешан vb.net и C#. Это будет переписан в какой-то момент)Обновление параллельного события UI

так в мои окна образуют я называю

progressBar.Visible = True 
    progressBar.Value = 0 
    progressBar.Maximum = dataGrid.SelectedRows.Count 

    AddHandler quoteManager.refreshStarted, AddressOf progressBarCounter 
    quoteManager.refreshAllAsync(list) 

и событие просто

Private Sub progressBarCounter() 
    Me.Invoke(Sub() 
        If progressBar.Value = progressBar.Maximum Then 
         progressBar.Visible = False 
        Else 
         progressBar.Value += 1 
        End If 
       End Sub) 
End Sub 

и в классе диспетчера котировок у меня это определено.

public event Action refreshStarted; 

    public void refreshAllAsync(List<BindableQuote> bindableQuotes) 
    { 
     bindableQuotes.AsParallel() 
      .WithDegreeOfParallelism(10) 
      .ForAll((quote) => { 
       quote.refreshAll(); 
       if (refreshStarted != null) { refreshStarted(); } 
      }); 
    } 

Так почему я получаю это ввести progressBarCounter по каждому пункту в списке, но он никогда не существует. Вместо этого он просто сохраняет форму замороженной.

ответ

0

Я не совсем уверен, что это то, что происходит, но похоже, что progressBarCounter блокируется, потому что вы вызываете Invoke. Если вместо этого вы используете BeginInvoke? Использование BeginInvoke может решить проблему взаимоблокировки. См. Это сообщение: What's the difference between Invoke() and BeginInvoke()

+0

да что работает !!! Однако не следует ли настраивать блокировку в этом разделе? Но по какой-то причине, по-видимому, – Leon 2010-11-26 20:33:19

0

Что здесь происходит, так это то, что вы получаете доступ к объектам пользовательского интерфейса из нескольких потоков.

Это не поддерживается. Вам нужно будет запустить этот код в рабочем потоке и позволить ему как-то накапливать прогресс и отправлять сообщения обратно в поток пользовательского интерфейса. Класс BackgroundWorker может помочь вам реализовать маршаллинг обратно в поток пользовательского интерфейса.

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