2014-08-27 5 views
1

ContinueWith()를 사용하여 async/await 및 chaining 작업을 사용하고 TaskContinuationOptions.NotOnFaulted를 사용하여 예외를 확인하면서 일부 기존 코드를 다시 작성하려고합니다.Task.ContinueWith()가 예상대로 실행되지 않습니다.

코드를 디버깅 할 때 예상대로 작동하지 않는 것으로 나타났습니다. 두 웹 요청이 모두 성공했지만 첫 번째 연속 만 응답을 처리합니다.

두 번째 지속은 를 완료하지 않고 마지막 날 결과를 제공합니다

Id = 1, Status = RanToCompletion, Method = "{null}", Result = "System.Threading.Tasks.Task`1[System.Threading.Tasks.VoidTaskResult]" 

하고 결과를 :

Id = 2, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}" 

내 질문은 내가 할 수 잘못하고 무엇을하고 무엇을 두 번째 연속이 완료되도록하십시오. ContinueWith를 사용하여 작업을 함께 연결하는 좋은 방법이라고 생각하거나 여러 가지 방법을 사용하지 않고도 더 좋은 방법이 있다면 관심이 있습니까? 도움 @ 벤 로빈슨처럼

using Newtonsoft.Json.Linq;     

    var api = new Api(); 
    var order = new Dictionary<string, object>(); 
    await api.MakeRequest(Api.Endpoint.Orders, HttpMethod.Get, null, "?completed=false&page=" + count) 
    //Look for new Orders 
    .ContinueWith(ant => 
    { 
      dynamic jsonOrder = JObject.Parse(ant.Result); 
      JArray data = jsonOrder.data; 
      //Process Json Response 
      order.Add("customer_name", (string)data[j]["customer_name"]); 
      order.Add("product_id", (string)data[j]["product_id"]); 
      order.Add("order_id", (string)data[j]["order_id"]); 
      order.Add("timestamp", (int)data[j]["timestamp"]); 
      //Entries are successfully added 
    }, TaskContinuationOptions.NotOnFaulted) 
    //Now get more details about the product 
    .ContinueWith(async (ant) => 
    { 
      string result = await api.MakeRequest(Api.Endpoint.Product, HttpMethod.Get, null, (string)order["product_id"]); 
      //The Request succeeds 

      //This code block does not execute 
      dynamic json = JObject.Parse(result); 
      order.Add("deadline", (int)json.data.deadline); 
      order.Add("price", (string)json.data.price); 
      order.Add("amount", (int)json.data.amount); 
      //This code block does not execute 

    }, TaskContinuationOptions.NotOnFaulted) 
    //Get some more details about the Customer (isRecurring? etc) 
    .ContinueWith(async (ant) => 
    { 
     //Some more code here 
    } 
+1

* 서투른 방법의 무리를 작성하지 않고 그것을 할 수있는 더 좋은 방법이 있는지? 구문의 * 사용 비동기/await를 –

+1

당신이 기다리고있는 작업을 ContinueWith 할 필요가 없습니다, 그건 요점 . 그냥 작업을 기다리고 기다린 후 코드는 작업이 완료되거나 실패 할 때만 실행됩니다. 기다리고있는 메서드에서 반환 한 값에서 결과를 추출합니다. 'var result = await api.MakeRequest (...'.) 예외 처리를 위해 표준 try/catch 구문을 사용할 수 있습니다 .. –

+0

네 말이 맞습니다.하지만 명령을 병렬로 처리하고 작업을 기다리지 않으려면 어떻게해야합니까? – Timo1995

답변

1

에 대한 덕분에 그렇지 않으면 예외가 발생, await의 사용이 자동으로 작업이 성공한 경우에만 실행되는 계속 같은 방법의 나머지를 등록했다. 제 방법을 변경하여 ContinueWith 호출을 제거하고 비동기 작업이 완료된 후 현재 SynchrionizationContext으로 돌아갈 필요가 없다면 ConfigureAwait(false)을 사용하십시오. 즉 나머지 메소드는 스레드 풀 스레드에서 계속 실행됩니다. 유용한 정보는 this article입니다.

var api = new Api(); 
var order = new Dictionary<string, object>(); 

await api.MakeRequest(Api.Endpoint.Orders, HttpMethod.Get, null, "?completed=false&page=" + count).ConfiugureAwait(false); 

//Look for new Orders 
dynamic jsonOrder = JObject.Parse(ant.Result); 
JArray data = jsonOrder.data; 
//Process Json Response 
order.Add("customer_name", (string)data[j]["customer_name"]); 
order.Add("product_id", (string)data[j]["product_id"]); 
order.Add("order_id", (string)data[j]["order_id"]); 
order.Add("timestamp", (int)data[j]["timestamp"]); 

//Now get more details about the product 
string result = await api.MakeRequest(Api.Endpoint.Product, HttpMethod.Get, null, (string)order["product_id"]).ConfiugureAwait(false); 

dynamic json = JObject.Parse(result); 
order.Add("deadline", (int)json.data.deadline); 
order.Add("price", (string)json.data.price); 
order.Add("amount", (int)json.data.amount); 
+0

하지만 왜 코드는 두 번째로 기다리고 있습니다 .ContinueWith가 실행됩니까? – tonlika