2011-12-27 3 views
1

내가 틀릴 수도 있지만 특정 순서에 상관하지 않으면 백그라운드 스레드가 List 또는 ObservableCollection에 읽고 쓸 수 있습니다. 만 약 주문이 필요한 경우 BlockingCollection을 사용합니다.작업을 실행하는 동안 UI가 고정되어 있습니다.

private void buttonTesting_Click(object sender, RoutedEventArgs e) 
    { 
     PrepareDataForTesting();     
     Stopwatch timer1 = new Stopwatch(); 
     timer1.Start();   

     //some code preparing data 

     List<Task> tasks = new List<Task>(); 

      //Testing for each pair 
     foreach (InterfaceWithClassName aCompound in Group1) 
     { 
      foreach (InterfaceWithClassName bCompound in Group2) 
      { 
       InstancePair pair = new InstancePair(); 
       //some code 

       Task task = Task.Factory.StartNew(() => TestPairSerial(pair)); 
       tasks.Add(task); 
      } 
      }     

      var ui = TaskScheduler.FromCurrentSynchronizationContext(); 

      Task.Factory.ContinueWhenAll(tasks.ToArray(), 
       antecedents => 
       { 
        timer1.Stop(); 
        TimeSpan ts1 = timer1.Elapsed; 
        string elapsedTime1 = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts1.Hours, ts1.Minutes, ts1.Seconds, ts1.Milliseconds/10); 
        statusLabel_1.Content = "Elapsed time to run the test" + elapsedTime1; 
        statusLabel_0.Content = "Testing made " + passes + " passes"; 
        pairsResultsDataGrid.ItemsSource = pairsResultsTable.DefaultView; 
        System.Media.SystemSounds.Exclamation.Play(); 

       }, CancellationToken.None, TaskContinuationOptions.None, ui);    

       System.Media.SystemSounds.Beep.Play();    
      } 

(참고 : 나는 중요한 경우에 확실하지 않다 - "쌍"반사를 통해 발견) 내가 마지막 줄들을 수있는 버튼을 클릭하면 - (System.Media.SystemSounds.Beep.Play를) ; 우리는 이벤트 핸들러에서 모든 스레드가 시작된다는 것을 의미합니다. 그러나 ContinueWhenAll이 완료 될 때까지 내 응용 프로그램은 여전히 ​​고정되어 있습니다.

private void TestPairSerial(object instances) 
    { 
     do 
     { 
      do 
      { 
      //here are two methods that read data from minData ObservableCollection 
      //minData is a public static property of MainWindow 
      //minData is bound to Chart control (in XAML) 

      } while (isSetbCompoundParams); 

     } while (isSetaCompoundParams); 

       //filling up results into one table and two dictionaries (main window variables) 
    } 
+0

나머지 방법을 보여줄 수 있습니까? 또한 UI가 멈 추면 실행을 일시 중지하고 mainthread가 중지 된 위치를 확인할 수도 있습니다. –

+0

나는 멈추려고했지만 예 (TestPairSerial 내부)는 여러 가지 방법 중 하나입니다. 죄송합니다. 너무 많고 너무 많은 코드가 있습니다 (본질을 보여주기 위해 최선을 다했습니다). – Vitaly

+0

MSDN 포럼에서 같은 질문을했습니다. 대답이 맞는 것처럼 보입니다. http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/74b2c600-83ad-4890-b2b2-27d8f07f5a90 – Vitaly

답변

0

는 메인 스레드의 작업을 실행되어 TestPairSerial (쌍) 방법은 다음의 구성을 갖는다. 비동기 적으로 코드 전체를 실행할 수 있습니다. Dispatcher.BeginInvoke

this.Dispatcher.BeginInvoke(new Action(() => { 
    // your code here 
}), null); 
+0

기본적으로 작업이 시작되면 즉시 비동기 적으로 실행됩니다. 다음 블로그를 예제로 사용했습니다. http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx – Vitaly

+0

사실입니다. , 나머지 코드는 그렇지 않습니다. 위의 블록에서 전체 코드를 래핑하는 것이 좋습니다. 유용 할 수 있습니다. –

+0

죄송합니다. 방금 시도했는데 작동하지 않았습니다. 같은 결과. 내 추측은 - 이유는 mainWindow 변수와 비동기 스레드 간의 지속적인 통신에 있습니다. – Vitaly

관련 문제