2013-09-06 9 views
8

Piszę klasy, które mają synchroniczne i asynchroniczne wersje tej samej metody void MyMethod(object argument) i Task MyMethodAsync(object argument). W wersji zsynchronizowanej sprawdzam poprawność argumentu za pomocą prostego sprawdzania. Jak powinien wyglądać ten sam sprawdzian w metodzie asynchronicznej?Sprawdzanie poprawności parametrów w asynchronicznej metodzie

1) Tak samo jak w przypadku metody synchronizacji

2) (aktualizacja po pierwszej odpowiedzi)

if (argument == null) 
    return new Task.Factory.StartNew(() => { throw new ArgumentNullException("argument"); }); 

Odpowiedz

6

To zależy trochę na kiedy chcesz błąd zostać podniesiona - tj niecierpliwością, lub jako część tego, co godne podziwu. Podobnie jak w przypadku bloków iteracyjnej, jeśli chcesz chętnych kontroli błędów, potrzebne są dwa sposoby, na przykład:

public Task<int> SomeMethod(..args..) { 
    if(..args fail..) throw new InvalidOperationException(...); 
    return SomeMethodImpl(...args...); 
} 
private async Task<int> SomeMethodImpl(...args...) 
{ 
    ... await etc ... 
} 

ten będzie następnie wykonać żadnego argumentu sprawdzania jako część pierwszego połączenia, nie awaitable. Jeśli chcesz wyjątek stanowić część awaitable, można po prostu wyrzucić go:

public async Task<int> SomeMethod(..args..) { 
    if(..args fail..) throw new InvalidOperationException(...); 
    ... await etc ... 
} 

Jednak w swojej przykład fakt, że jesteś return ing Task sugeruje, że nie jest to faktycznie metoda async, ale jest to metoda async (ale nie async). Nie można po prostu zrobić:

return new Task(() => { throw new ArgumentNullException("argument"); }); 

bo Task nigdy nie zostały uruchomione - i nigdy nie będzie. I podejrzany trzeba by zrobić coś takiego:

try { 
    throw new InvalidArgumentException(...); // need to throw to get stacktrace 
} catch(Exception ex) { 
    var source = new TaskCompletionSource<int>(); 
    source.SetException(ex); 
    return source.Task; 
} 

który jest ... trochę łyk i prawdopodobnie mógłby być obudowane nieco lepiej. To zwróci wartość Task, która wskazuje, że znajduje się ona w stanie Faulted.

+0

Docelowy framework to 4.0, więc nie używam asynchronicznego i oczekuję słów kluczowych. – Demarsch

+0

Druga opcja powinna być napisana jako Task.Factory.StartNew (() => {throw ...}); Zaktualizował go w pytaniu – Demarsch

+0

@Demarsch po prostu dodaj [Microsoft.Bcl.Async] (https://www.nuget.org/packages/Microsoft.Bcl.Async) i 'async' /' czekaj' działa dobrze –

3

Po prostu wyrzuć tak, jak zrobiłeś w metodzie synchronizacji, TPL ma różne mechanizmy, aby ponownie rzucić wyjątek, na przykład po przeczytaniu. Result Właściwość lub dostęp. Właściwość Exception.

Powiązane problemy