2013-02-26 184 views
0

請多多包涵:-)多個異步任務執行

我與TPL在C#中掙扎,我堅持試圖找出設計的開球多個異步任務的解決方案的最佳方式,等待他們完成並繼續前進。我最初的POC在下面。每個IDataGatherer實例都需要獲取數據並將其按摩到一個DataObject實例中。

  1. 我不確定如何處理從DownloadStringTaskAsync電話,這樣我可以把結果和按摩到一個數據對象的延續。 ContinueWith想要提供一個帶void返回簽名的方法,但我覺得ExtractData方法需要返回一個Task實例,否則我沒有一個Task實例從GetDataAsync()方法返回。

  2. 我也想知道如果我需要在我的IDataGatherer實例中引入TaskCompletionSource,但是我如何將這些操作綁定到正在進行實際工作的任務上 - 例如DownloadstringTaskAsync和ExtractData?

interface IDataGatherer 
{ 
    Task<DataObject> GetDataAsync(); 
} 

class DataObject 
{ 
    public string Data { get; set; } 
} 

class IpGatherer : IDataGatherer 
{ 
    private readonly string _url = "http://ip.jsontest.com"; 

    public Task<DataObject> GetDataAsync() 
    { 
     var tcs = new TaskCompletionSource<DataObject>(); // Do I need this??? 

     var client = new WebClient(); 

     // stuck here 
     var task = client.DownloadStringTaskAsync(_url).ContinueWith(ExtractData); 
    } 

    private void ExtractData(Task<string> obj) 
    { 

    } 
} 

class Program 
{ 
    private static void Main(string[] args) 
    { 
     // takes a list of IDataGatherers and waits for them 
     // all to complete, handles exceptions, etc. 
    } 
} 

設計的解決方案這種方式可能是過於複雜的事情,所以我願意接受建議清理東西或做他們更加簡潔。

我使用.NET 4.5

+0

什麼版本的.NET? 4.0或4.5? – 2013-02-26 20:30:39

回答

2

首先,你不需要TaskCompletionSource。這是因爲ContinueWith()可以提供一個非void簽名的方法。例如:

public Task<DataObject> GetDataAsync() 
{ 
    var client = new WebClient(); 

    return client.DownloadStringTaskAsync(_url) 
       .ContinueWith((Func<Task<string>, DataObject>)ExtractData); 
} 

private DataObject ExtractData(Task<string> task) 
{ 
    return new DataObject(task.Result); 
} 

(使用Result不會阻止,因爲你可以肯定的Task將在此時完成。)

但由於您使用的DownloadStringTaskAsync(),你很可能會在。 Net 4.5,這意味着你可以使用await。這使得代碼更加簡單:

public async Task<DataObject> GetDataAsync() 
{ 
    var client = new WebClient(); 

    var s = await client.DownloadStringTaskAsync(_url); 
    return ExtractData(s); 
} 

private DataObject ExtractData(string s) 
{ 
    return new DataObject(s); 
} 
+0

甜!在我的挫折中,我沒有考慮將ExtractData函數轉換爲可接受的重載。咄!我正在使用.Net 4.5,所以我將使用async/await代碼運行,因爲它更簡單,就像您所說的那樣。謝謝! – John 2013-02-26 21:50:32