2013-02-26 4 views
0

을 기다리고, 나는 C#을에 TPL과 사투를 벌인거야여러 비동기 작업 실행

:-) 나와 함께 곰 여러 비동기 작업을 발로위한 솔루션을 설계하는 가장 좋은 방법을 알아 내려고 붙어하세요 그들을 완료하고, 계속 나아 간다. 내 초기 POC는 아래에 있습니다. 각 IDataGatherer 인스턴스는 데이터를 가져와 DataObject 인스턴스로 가져와야합니다.

  1. 가 나는 결과를 가지고와 데이터 객체로 마사지 할 수 있도록 DownloadStringTaskAsync 호출의 지속을 처리하는 방법의 확실 해요. ContinueWith는 void 반환 시그니처가있는 메서드를 제공하려고하지만 ExtractData 메서드가 Task 인스턴스를 반환해야하거나 그렇지 않으면 GetDataAsync() 메서드에서 반환 할 Task 인스턴스가없는 것 같습니다.

  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? –

답변

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); 
} 

을 (당신이 Task이 그 시점에서 완료됩니다 확신 할 수 있기 때문에, 차단하지 않습니다 Result 사용.)하지만 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 함수를 허용 가능한 오버로드로 캐스팅하지 않을 것이라고 생각했다. 이런! 닷넷 4.5를 사용하고 있기 때문에 async/await 코드를 실행하면서 간단하게 설명하겠다. 감사! – John