2013-07-09 23 views
1

我有一個類,每個方法異步執行,即返回一個任務,但每個方法應該等待前面的調用完成。延續任務(而不是代表)

繼續吧?

除了任務繼續在參數中使用委託(Action)而不是另一個任務。

我已經嘗試不同的東西,我可以做,使之工作最好的是以下(對我來說太複雜了)代碼:

private Task QueueTask(Func<Task> futureTask) 
    { 
     var completionSource = new TaskCompletionSource<int>(); 

     _lastTask.ContinueWith(async t => 
     { 
      try 
      { 
       await futureTask(); 

       completionSource.SetResult(0); 
      } 
      catch (Exception ex) 
      { 
       completionSource.SetException(ex); 
      } 
     }); 

     _lastTask = completionSource.Task; 

     return _lastTask; 
    } 

這裏_lastTask是我班的私有成員。由於所有調用都來自UI線程,因此我只保留最後一項任務並將其繼續。

正如我所說我覺得這個代碼相當複雜。你有更好的建議嗎?

+0

目前還不清楚你實際上做了什麼你想要的東西。 ''Func '方法做什麼?如果他們正在創造自己的任務,他們是否也開始呢?如果你可以提供一個簡短但完整的例子,那真的很有幫助。 –

+0

另外,你見過接受'Func <任務,任務>'的'ContinueWith'的重載嗎?似乎問題更多的是你忽略了現有的任務部分,而不是返回值部分...... –

回答

2

對我來說,好像你在問錯誤的問題。像這樣的任務隊列是一個不尋常的要求。我們對您要解決的實際問題一無所知,因此我們無法提出更好的方法。

ContinueWith是用於動態並行處理,所以它不是相當於適合於async的代碼。但是,您可以使用ContinueWithUnwrap配對來模擬await的行爲(如果忽略await與當前上下文的交互方式)。

所以您可以簡化的任務隊列解決這樣:

private Task QueueTask(Func<Task> futureTask) 
{ 
    _lastTask = _lastTask.ContinueWith(t => futureTask()).Unwrap(); 
    return _lastTask; 
} 

不過,也有可能是更好的解決方案。如果隊列的目的是提供排他性訪問,那麼SemaphoreSlim會更自然。如果您出於某種原因確實需要隊列,請考慮使用Dataflow網格。