2012-11-29 31 views
2

我在學習Task如何工作。我一直使用BackgroundWorker類或Threading.Thread類,所以我想品嚐Task Factory。Task.Factory.StartNew和主UI

在下面的例子中我建設,我恢復

Task<List<People>> 

併爲其分配一個「ContinueWith」我希望當任務完成後調用。

我這樣做,是被工作真棒以前的一些例子,但在應用程序啓動這一凍結我

主要形式的UI。 (我看不到與其他我沒有做過的其他例子的區別)。

你知道爲什麼我的主界面凍結了嗎?

PS:我知道我的任務聲明中聲明

System.Threading.Tasks.TaskScheduler scheUI 

。我現在沒有使用,但我會在以後。

在此先感謝:

下面是代碼:

private void PopulateList(List<People> list) 
      { 
       if (listBox1.InvokeRequired) 
       { 
       listBox1.Invoke((MethodInvoker) delegate { 

        foreach (People item in list) 
        { 
         listBox1.Items.Add(item.name + " " + listBox1.Items.Add(item.surname)); 
        } 

       }); 
      } 
     } 



private Task<List<People>> GetPeopleListAsync(int PeopleNuber, int delaysecs) 
     { 
     TaskScheduler scheUI = TaskScheduler.FromCurrentSynchronizationContext(); 
      return Task<List<People>>.Factory.StartNew(() => 
       { 
        List<People> listado = new List<People>(); 

        for (int i = 0; i < PeopleNuber; i++) 
        { 
         People people = new People 
         { 
          name = "Name" + i.ToString(), 
          surname = "Surname " + i.ToString() 
         }; 

         Thread.Sleep(delaysecs * 200); 
         listado.Add(people); 
        } 

        return listado; 


       },CancellationToken.None, 
       TaskCreationOptions.None,scheUI); 

     } 


void Form1_Load(object sender, EventArgs e) 
{ 


      Task<List<People>> task = GetPeopleListAsync(5, 10); 
      task.ContinueWith(p => PopulateList(task.Result)); 
} 
+0

您的PC有多少核心?由於不能保證任務會在單獨的線程中運行,我猜測可能是所有的東西都在同一個線程中運行。 –

+1

爲了調試目的,嘗試使用以下選項創建任務System.Threading.Tasks.TaskCreationOptions.LongRunning –

+0

是否有某些原因導致您沒有'使用System.Threading.Tasks'?它真的讓你的代碼無處不在。 – Servy

回答

4

您正在使用同步的第一個任務與UI線程:

System.Threading.Tasks.TaskScheduler scheUI = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext(); 

從第一取出scheUI調度任務:

return System.Threading.Tasks.Task<List<People>>.Factory.StartNew(() => 
      { 
       List<People> listado = new List<People>(); 

       for (int i = 0; i < PeopleNuber; i++) 
       { 
        People people = new People 
        { 
         name = "Name" + i.ToString(), 
         surname = "Surname " + i.ToString() 
        }; 

        System.Threading.Thread.Sleep(delaysecs * 200); 
        listado.Add(people); 
       } 

       return listado; 


      }); 

您應該將同步添加到執行的第二個任務以更新您的用戶界面:

System.Threading.Tasks.TaskScheduler scheUI = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext(); 
task.ContinueWith(p => PopulateList(task.Result),CancellationToken.None, 
           TaskContinuationOptions.ExecuteSynchronously | 
           TaskContinuationOptions.OnlyOnRanToCompletion, 
           scheUI); 
+0

我應該聲明Task:System.Threading.Tasks.TaskScheduler.Default); ? –

+0

我編輯了我的答案。如果你不需要它,不需要使用任何TaskScheduler。 – margabit

+0

非常感謝你 –

相關問題