2013-02-26 213 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