2011-12-27 50 views
1

可能是我錯了,但我的推測是任何後臺線程都可以讀取和寫入List或ObservableCollection,如果我不關心任何特定的順序。如果我需要一個確定的順序,我將使用BlockingCollection。用戶界面在運行時被凍結任務

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完成。 TestPairSerial(對)方法具有如下結構:

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停止的位置。 – 2011-12-28 15:48:33

+0

我試圖暫停,是的它是在多個方法之一(TestPairSerial內)。對不起,有太多的代碼和太多的代碼顯示(我盡我所能展示了本質)。 – Vitaly 2011-12-28 15:59:30

+0

我試圖在MSDN論壇上提出同樣的問題。看起來他們的答案是有道理的。 http://social.msdn.microsoft.com/Forums/en-US/parallelextensions/thread/74b2c600-83ad-4890-b2b2-27d8f07f5a90 – Vitaly 2011-12-28 16:02:25

回答

0

您正在執行在主線程的任務。你可以執行整個代碼與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 2011-12-27 19:02:27

+0

這是真的,但其餘的代碼不會。在我建議的上面的代碼塊中包裝你的整個代碼並沒有什麼壞處。你可能會覺得它很有用。 – 2011-12-27 19:05:21

+0

對不起。我剛試過它沒有用。結果相同。我的猜測是 - 原因是在mainWindow變量和異步線程之間經常進行通信。 – Vitaly 2011-12-27 19:20:25