2013-07-16 2 views
16

...Async으로 끝나는 메소드와 Task을 제공하는 라이브러리를 사용하고 있습니다. 나는 이것을 명령 행 응용 프로그램에서 사용할 것이다. 그래서 그것들을 동 기적으로 많이 호출해야합니다.AggregateException에서 예외를 래핑하지 않고 비동기 작업을 기다립니다.

Main 메서드에서 async 수정자를 사용할 수 없기 때문에 물론 # Main 메서드에서 이러한 메서드를 호출 할 수 없습니다. 가정이 작업입니다 : 내가 좋아하는 몇 가지 솔루션을 발견

var task = datastore.Save(data); 

: AggregateException

Tasks.WaitAll(task); 
task.Wait(); 

그러나이 모든 랩 던져 예외를 내가 것을 원하지 않는다. 그냥 라고 말하고 싶습니다. 원본 예외가 발생하기를 기대합니다.

Task<TResult>을 반환하는 메서드를 사용할 때 task.Result은 연속 작업이 설정되어 있지 않아도 AggregateException을 throw합니다. 왜 이런 일이 일어나고있는거야?

RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.

그래서 난 그 async로 표시 방법이 아니 것 같아요 :

나는 또한 시도했다

task.RunSynchronously(); 

그것은 오류가 있습니다.

비동기 컨텍스트가없는 콘솔 앱에서 비동기 앱용으로 설계된 라이브러리를 사용하는 패턴에 대한 아이디어가 있습니까?

답변

27

I am going to use these in a command line application. So I need to call them synchronously a lot.

아니, 당신은하지 않습니다. 콘솔 응용 프로그램에서 async - await을 사용하면 가장 상단에 비동기 동기화 전환을 만들어야합니다. 그리고 당신은 Wait()을 사용하여 해당 작업을 수행 할 수 있습니다

public static void Main() 
{ 
    MainAsync().Wait(); 
} 

public static async Task MainAsync() 
{ 
    var datastore = …; 
    await datastore.SaveAsync(); 
} 

일반적으로 Wait()await 결합하는 것은 좋은 생각 (이것은 교착 상태가 발생할 수)이지만, 여기에 적합한 솔루션입니다.

SaveAsync()이 예외를 throw하고 catch하지 않으면 에서 AggregateException으로 다시 전달됩니다. 그러나 MainAsync()에 원래 예외로 붙잡을 수 있습니다 (을 사용하지 않으므로).

직접 던진 첫 번째 예외를 실제로 얻으려면 await과 비슷한 작업을 수행 할 수 있습니다 (task.GetAwaiter().GetResult()). Task에 둘 이상의 예외가 포함되어있는 경우 첫 번째 값만 가져옵니다 (단, await에도 동일하게 적용됩니다).

When I use a method returning Task<TResult> , task.Result throws AggregateException even though there are no continuation tasks set. Why is this happening?

이것은 계속과 관련이 없습니다. 단일 Task은 여러 연산을 나타낼 수 있으며 각 연산은 예외를 throw 할 수 있습니다. 그 때문에 Task 메서드 은 항상이고 예외는 AggregateException에 래핑됩니다.

I also have tried task.RunSynchronously()

그건 의미가 없습니다. RunSynchronously()Task 생성자를 사용하여 생성 된 Task에서만 사용할 수 있습니다. 여기서는 그렇지 않아서 사용할 수 없습니다. 비동기 메서드에서 반환 된 Task은 항상 이미 시작되었습니다.

2

당신은 참조, 또한이 대답을 더미 Main

public static void Main() 
{ 
    MainAsync().Wait(); 
} 

public static async Task MainAsync() 
{ 
    try { 
     var result = await dataStore.Save(data); 
    } catch(ExceptionYouWantToCatch e) { 
     // handle it 
    } 
} 

를 만들 수 있습니다 https://stackoverflow.com/a/9212343/1529246

관련 문제