2013-09-06 3 views
8

Я пишу класс, который имеет синхронные и асинхронные версии того же метода void MyMethod(object argument) и Task MyMethodAsync(object argument). В синхронизации версии я проверить аргумент с простой проверкойПроверка параметров в методе async

if (argument == null) 
    throw new ArgumentNullException("argument"); 

Как должен же проверка выглядеть в методе асинхронной?

1) То же, как для метода синхронизации

2) (Обновлено после первого ответа)

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

ответ

6

Это зависит немного о том, когда вы хотите, чтобы ошибки быть подняты - т.е. жадности, или как часть от ожидаемого. Как и блоков итераторов, если вы хотите, жаждущих проверки ошибок, вам нужно два метода, например:

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

Это будет выполнять любой аргумент проверки как часть первоначального вызова, не awaitable. Если вы хотите исключение быть частью awaitable, вы можете просто бросить его:

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

Однако, в вашем примере, тот факт, что вы return ING Task предполагает, что это не на самом деле async метод, но это async (но не async) метод. Вы не можете просто сделать:

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

, потому что никогда не было начато, что Task - и никогда не будет. Я подозреваемого вы должны сделать что-то вроде:

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

который ... немного глотки и, вероятно, может быть воплощен немного лучше. Это вернет Task, который указывает, что он находится в состоянии Faulted.

+0

Целевая структура 4.0, поэтому я не использую async и жду ключевых слов – Demarsch

+0

Второй вариант должен быть написан как Task.Factory.StartNew (() => {throw ...}); Обновлено в вопросе – Demarsch

+0

@ Demarsch просто добавьте [Microsoft.Bcl.Async] (https://www.nuget.org/packages/Microsoft.Bcl.Async) и 'async' /' await' будет работать нормально –

3

Просто бросьте его так же, как в методе синхронизации, TPL имеет различные механизмы для повторного выброса исключения, например, когда вы читаете. Result собственности или доступа. Exception Недвижимость.

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