2016-01-15 4 views
3

У меня есть проект, где у нас есть каталог действий. В основе каждого действия может быть один из сетевых вызовов. Итак, основной метод выглядит примерно так:Рефактор асинхронный метод

public async Task<Result> evaluate(){ 
//some setup chunk 
     try 
     { 
      responsefromUri = await requestManager.Post(resourceUri, ""); 
     } 
      // The non-retryable exception will directly trickle up. 
     catch (RetryableException exception) 
     { 
      return BuildFailedCheckResult(
       StatusCode.Abandoned, 
       Check1 + " abandoned. Failed to read the response for resource: " + resourceUri + " with exception: " + exception.Message); 
     } 

     if (string.IsNullOrEmpty(responsefromUri)) 
     { 
      return BuildFailedCheckResult(
       StatusCode.Failed, 
       Check1 + " failed. Empty response for resource: " + resourceUri); 
     } 

     try 
     { 
      responseJson = JObject.Parse(responsefromUri); 
     } 
     catch (JsonReaderException e) 
     { 
      throw new InvalidOperationException(Check1 + " check failed parsing resource: " + resourceUri, e); 
     } 
// use responseJson to get data and process further 
} 

Этот кусок для каждого сетевого вызова. Я хочу это извлечь. Теперь я не могу этого сделать, потому что есть ожидание и его извлечь. Мне нужен метод async; но для возврата результата неудачной проверки мне нужна переменная out, которая не допускается в асинхронных методах. Каким будет правильный способ реорганизации этого кода? Метод становится раздражающе длинным, когда есть несколько сетевых вызовов.

ответ

1

Просто упакуйте свою «дальнейшую обработку» в Func, например.

public async Task<Result> evaluate(Uri resourceUri, Func<JObject, Result> action) 
{ 
    string responsefromUri; 

    try 
    { 
     responsefromUri = await requestManager.Post(resourceUri, ""); 
    } 
     // The non-retryable exception will directly trickle up. 
    catch (RetryableException exception) 
    { 
     return BuildFailedCheckResult(
      StatusCode.Abandoned, 
      Check1 + " abandoned. Failed to read the response for resource: " + resourceUri + " with exception: " + exception.Message); 
    } 

    if (string.IsNullOrEmpty(responsefromUri)) 
    { 
     return BuildFailedCheckResult(
      StatusCode.Failed, 
      Check1 + " failed. Empty response for resource: " + resourceUri); 
    } 

    JObject responseJson; 
    try 
    { 
     responseJson = JObject.Parse(responsefromUri); 
    } 
    catch (JsonReaderException e) 
    { 
     throw new InvalidOperationException(Check1 + " check failed parsing resource: " + resourceUri, e); 
    } 

    return action(responseJson); 
} 

Пример:

// Example Usage 
public Task<Result> DoStuff() 
{ 
    Uri uri = new Uri("http://localhost"); 

    return evaluate(uri, jobject => { 
     return new Result(jobject["result"]); 
    }); 
} 
0

вы можете реорганизовать кусок кода, чтобы быть в отдельном частном методе возвращающей задачу и добавить класс JsonResult, который будет содержать «счастливый-путь» результат

Смежные вопросы