2012-11-20 20 views
3

什麼是並行下面的代碼的正確語法?Task.Factory.StartNew(的someMethod(withParam))。continueWith(sameMethod(differentParam))。等待()

static void Main(string[] args) 
{ 
    Task.Factory.StartNew(
     () => 
      doOne(SelectedTask.option1) 
      .ContinueWith(
      task => 
      doOne(SelectedTask.option1)).Wait() 
    ); 
} 

enum「selectedTask」同樣的方法來決定執行其代碼:

static enum SelectedTask 
{ 
    option1, 
    option2 
} 

static void doOne(SelectedTask Lunch) 
{ 
    switch (lunch) 
    { 
     case SelectedTask.option1: 
      Console.WriteLine("option1"); 
      break; 
     case SelectedTask.option2: 
      Console.WriteLine("option2"); 
      break; 
     default: 
      break; 
    } 
} 

回答

13

你想讓你的doOne調用同時發生嗎?然後,你可以開始他們直接從任務工廠:

// Start two concurrent tasks 
var task1 = Task.Factory.StartNew(() => doOne(SelectedTask.option1)); 
var task2 = Task.Factory.StartNew(() => doOne(SelectedTask.option2)); 

// Block the current thread until all tasks complete 
Task.WaitAll(task1, task2); 

你想對你doOne調用順序發生?然後,你可以把它們用ContinueWith鏈條:

// Start a chain of tasks 
var task1 = Task.Factory.StartNew(() => doOne(SelectedTask.option1)); 
var task2 = task1.ContinueWith(t => doOne(SelectedTask.option2)); 

// Block the current thread until the last task completes 
task2.Wait(); 

在您的文章的標題(一對夫婦修復)的代碼基本上執行完全相同的功能,如我上面的順序任務鏈:

Task.Factory.StartNew(() => doOne(SelectedTask.option1)) 
      .ContinueWith(t => doOne(SelectedTask.option2)) 
      .Wait(); 

回答你的問題。

如果我理解正確的話,你要能夠運行一個任務的SelectedTasks並行變量列表:

List<SelectedTask> selectedTaskOptions = new List<SelectedTask>() 
{ 
    SelectedTask.option1, 
    SelectedTask.option2, 
    SelectedTask.option3, 
    SelectedTask.option4, 
    SelectedTask.option5 
}; 

RunAllSelectedTaskOptions(selectedTaskOptions); 

RunAllSelectedTaskOptions接受和運行的SelectedTasks列表:

public void RunAllSelectedTaskOptions(List<SelectedTask> selectedTaskOptions) 
{ 
    List<Task> createdTasks = new List<Task>(); 

    foreach(var taskOption in selectedTaskOptions) 
    { 
     createdTasks.Add(Task.Factory.CreateNew(() => doOne(taskOption))); 
    } 

    Task.WaitAll(createdTasks); 
} 

實施RunAllSelectedTaskOptions的另一種方式是使用Parallel.ForEach,這將並行執行,並且將阻塞,直到最慢/最後的迭代已完成:

public void RunAllSelectedTaskOptions(List<SelectedTask> selectedTaskOptions) 
{ 
    Parallel.ForEach(selectedTaskOptions, taskOption => doOne(taskOption)); 
} 
+1

非常感謝,它(回答中的最後一個示例)還接受傳遞給'doOne()'的參數,僅.. 。不是通過並行執行,而是通過一個典雅的代碼行,最後一個問題,如果我可能會問,唯一的選擇是並行運行任務將是第一個例子?它將每個任務聲明爲獨立聲明,然後執行Task.WaitAll()。總而言之,你知道一個優雅的方法來獲得一個類,它有5-10個方法,比如(option1,2 3 4 ...)並執行一堆,未來至少有10個(無論是否在一個班級或不(如果我們選擇)可以做到嗎? – LoneXcoder

+1

更新了我的答案! :) – davenewza

+0

看起來不錯,要檢查! (你知道我使用枚舉作爲參數有點選擇器..) – LoneXcoder

1

我假設你正在談論並行兩個doOne電話?

如果是這樣,那麼你需要做這樣的事情:

var task1 = Task.Factory.StartNew(() => doOne(SelectedTask.option1)); 
var task2 = Task.Factory.StartNew(() => doOne(SelectedTask.option2)); 
var taskList = new List<Task>{task1, task2}; 
Task.WaitAll(taskList); 

*上面的代碼是相當準確的,但語法沒有經過驗證。

+0

所以我想'Task.Factory'被限制爲空(無參數)的方法,以及使用一個列表將表現相同的方式'Task.Factory.StartNew()',僅型差分是與代碼在你的答案中,它允許你傳遞參數給方法? – LoneXcoder

+0

你沒有得到準確的唯一的事情是在你爲WaitAll ToArray的()...參數只能是數組而不是列表 – LoneXcoder

+0

@LoneXcoder您可以通過關閉傳遞參數(但你應該這樣做謹慎)或通過通用StartNew的動作版本:http://msdn.microsoft.com/en-us/library/dd321456.aspx –