2013-09-06 45 views
8

Tôi đang viết một lớp có phiên bản đồng bộ và không đồng bộ của cùng một phương thức void MyMethod(object argument)Task MyMethodAsync(object argument). Trong phiên bản đồng bộ hóa, tôi xác thực đối số bằng séc đơn giảnXác thực tham số theo phương thức không đồng bộ

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

Làm cách nào để kiểm tra giống như trong phương pháp không đồng bộ?

1) Tương tự như đối với phương pháp đồng bộ

2) (Cập nhật sau khi trả lời đầu tiên)

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

Trả lời

6

Điều đó phụ thuộc một chút vào khi bạn muốn các lỗi được nâng lên - tức là hăm hở, hoặc là một phần của các awaitable. Như với khối iterator, nếu bạn muốn kiểm tra lỗi háo hức, bạn cần hai phương pháp, ví dụ:

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

này sau đó sẽ thực hiện bất kỳ tranh luận kiểm tra như là một phần của cuộc gọi ban đầu, không phải là awaitable. Nếu bạn muốn các ngoại lệ là một phần của các awaitable, bạn chỉ có thể ném nó:

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

Tuy nhiên, trong ví dụ của bạn, thực tế là bạn đang return ing một Task gợi ý rằng đây không phải là thực sự là một phương pháp async, nhưng là một phương thức async (nhưng không phải là async). Bạn không thể chỉ làm:

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

vì điều đó Task sẽ không bao giờ được bắt đầu - và sẽ không bao giờ xảy ra. Tôi nghi ngờ bạn sẽ cần phải làm điều gì đó như:

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

đó là ... một chút của một mouthful và có lẽ có thể được gói gọn một chút tốt hơn. Điều này sẽ trả về một số Task cho biết nó ở trạng thái Faulted.

+0

Khung mục tiêu là 4.0 nên tôi không sử dụng không đồng bộ và đang chờ từ khóa – Demarsch

+0

Tùy chọn thứ hai nên được viết là Task.Factory.StartNew (() => {throw ...}); Cập nhật nó trong câu hỏi – Demarsch

+0

@Demarsch chỉ cần thêm [Microsoft.Bcl.Async] (https://www.nuget.org/packages/Microsoft.Bcl.Async) và 'async' /' await' sẽ hoạt động tốt –

3

Đơn giản chỉ cần ném nó như bạn đã làm trong phương pháp đồng bộ, TPL có nhiều cơ chế khác nhau để tái ném ngoại lệ, ví dụ khi bạn đọc. Result thuộc tính hoặc quyền truy cập. Exception tài sản.

Các vấn đề liên quan