2011-03-18 31 views
2

我有一個返回IEnumerable的類。然後我按順序執行這些任務。假設這個類是TaskProvider。使用TPL連續運行多個任務序列

public class TaskProvider { 
    public IEnumerable<Task> SomeThingsToDo() { return work; } 
} 

我執行這些有以下幾點:

public void ExecuteTasks(IEnumerable<Task> tasks) 
{ 
    var enumerator = tasks.GetEnumerator(); 
    ExecuteNextTask(enumerator); 
} 

static void ExecuteNextTask(IEnumerator<Task> enumerator) 
{ 
    bool moveNextSucceeded = enumerator.MoveNext(); 

    if (!moveNextSucceeded) return; 

    enumerator 
     .Current 
     .ContinueWith(x => ExecuteNextTask(enumerator)); 
} 

現在我有一個情況我可能有TaskProvider的多個實例,每個生成的任務列表。我希望按順序執行每個任務列表,這意味着來自一個提供程序的所有任務在下一個任務開始之前完成。

然後,最重要的是,我需要知道所有任務何時完成。

完成此操作的TPL方式是什麼?

(FWIW,我使用的是異步CTP爲Silverlight)。

+0

我也想知道如果我用我的ExecuteTask邏輯重新發明輪子。 – 2011-03-18 15:23:38

回答

1

這是我採取的方法,到目前爲止我所有的測試都通過了。

首先,我創建了一個聯合在一起枚舉所有的任務,可以從不同的供應商:

var tasks = from provider in providers 
      from task in provider.SomeThingsToDo() 
      select task; 

我相信我原來的問題的一部分是,我做了一個ToList(或多或少),從而開始了過早執行任務。

接下來,我添加了一個回調ExecuteTasks和ExecuteNextTask。誠然,並不像我希望的那麼幹淨。這裏是修改後的實現:

public void ExecuteTasks(IEnumerable<Task> tasks, Action callback) 
{ 
    var enumerator = tasks.GetEnumerator(); 
    ExecuteNextTask(enumerator, callback); 
} 

static void ExecuteNextTask(IEnumerator<Task> enumerator, Action callback) 
{ 
    bool moveNextSucceeded = enumerator.MoveNext(); 

    if (!moveNextSucceeded) 
    { 
     if (callback != null) callback(); 
     return; 
    } 

    enumerator 
     .Current 
     .ContinueWith(x => ExecuteNextTask(enumerator, callback)); 
} 

我不需要線程安全的結構來存儲任務列表,因爲列表只生成一次。

0

在最壞的情況,你可以有Ienumerables的靜態concurrentqueue您ExecuteNextTask方法的工作原理是通過路...

是這樣的:

public static class ExecuteController { 

    private static ConcurrentQueue<IEnumerable<Task>> TaskLists = new ConcurrentQueue<IEnumerable<Task>>(); 

    public void ExecuteTaskList(IEnumerable<Task> tasks) { 
      TaskLists.Enqueue(tasks); 
      TryStartExec(); 
    }   

    public void TryStartExec() { 
     check if there is a new task list and if so exec it with your code. 
     possibly need to lock around the dequeue but i think there is an atomic dequeue method on concurrent queue.. 
    } 

} 
+1

ConcurrentQueue 在Silverlight中(或在新的異步ctp庫中)不存在。儘管我現在正在根據你的回答採用類似的方法進行試驗。 – 2011-03-18 15:41:28