2010-11-22 23 views
100

Tôi đang triển khai phương thức Task<Result> StartSomeTask() và xảy ra để biết kết quả đã có trước khi phương thức được gọi. Làm cách nào để tạo một Task<T> đã hoàn thành?Tạo một Công việc hoàn thành <T>

Đây là những gì tôi đang thực hiện:

private readonly Result theResult = new Result(); 

public override Task<Result> StartSomeTask() 
{ 
    var task = new Task<Result>(() => theResult); 
    task.RunSynchronously(CurrentThreadTaskScheduler.CurrentThread); 
    return task; 
} 

Có một giải pháp tốt hơn?

+6

Lưu ý, câu trả lời cho câu hỏi này cũng chỉ hoạt động tốt khi tạo Tác vụ đơn giản (no ) vì Tác vụ được kế thừa từ Tác vụ. –

Trả lời

102
private readonly Result theResult = new Result(); 

public override Task<Result> StartSomeTask() 
{ 
    var taskSource = new TaskCompletionSource<Result>(); 
    taskSource.SetResult(theResult); 
    return taskSource.Task; 
} 
162

Khi nhắm mục tiêu NET 4.5 bạn có thể sử dụng Task.FromResult:

public static Task<TResult> FromResult<TResult>(TResult result); 

Để tạo một nhiệm vụ thất bại, sử dụng Task.FromException:

public static Task FromException(Exception exception); 
public static Task<TResult> FromException<TResult>(Exception exception); 

.NET 4.6 cho biết thêm Task.CompletedTask nếu bạn cần một tổ chức phi generic Task.

public static Task CompletedTask { get; } 

Cách giải quyết cho các phiên bản cũ của .NET:

  • Khi nhắm mục tiêu NET 4.0 với Async Nhắm mục tiêu Pack (hoặc AsyncCTP), bạn có thể sử dụng TaskEx.FromResult để thay thế.

  • Để có được phi generic Task trước .NET 4.6, bạn có thể sử dụng thực tế là Task<T> xuất phát từ Task và chỉ cần gọi Task.FromResult<object>(null) hoặc Task.FromResult(0).

+13

Để trả về một tác vụ không chung chung, tốt hơn nên sử dụng một cái gì đó như Task.FromResult (0). Sử dụng "null" làm tham số có thể gây nhầm lẫn trình biên dịch không thể xác định tham số chung. – Whyllee

+0

Còn ngoại lệ thì sao? Các phương thức không đồng bộ được biên dịch thành máy trạng thái bắt các ngoại lệ và lưu chúng trong nhiệm vụ trả về. Điều này xảy ra ngay cả khi thực thi mã trước khi chờ đợi đầu tiên. Phương thức trả về Task.FromResult có thể ném trực tiếp các ngoại lệ. –

+0

@ RobertVažan Một trường hợp thú vị. Có thể cho rằng, nếu bạn đang truy xuất kết quả __ đã biết của mình từ một phương thức và phương thức đó sẽ ném ngoại lệ thì có một lỗi mà cần sửa chữa. – Gusdor

1

Nếu bạn đang sử dụng Rx, một giải pháp thay thế là có thể quan sát.Return (result) .ToTask().

12

Đối với các tác vụ không có giá trị trả về, .NET 4.6 đã thêm Task.CompletedTask.

Nó trả về một tác vụ đã có trong TaskStatus.RanToCompletion. Nó có thể trả về cùng một ví dụ mỗi lần, nhưng tài liệu cảnh báo bạn không được tính vào thực tế đó.

0

Gọi nhiệm vụ.WhenTất cả mà không có bất kỳ thông số nào sẽ trả lại tác vụ đã hoàn thành.

Task task = Task.WhenAll(); 
Các vấn đề liên quan