2012-11-14 31 views
10

Điều gì sẽ là lựa chọn tốt nhất cho từ khóa chờ đợi trong .NET 4.0? Tôi có một phương thức cần trả về một giá trị sau một phép toán không đồng bộ. Tôi nhận thấy phương thức wait() khóa hoàn toàn luồng, do đó làm cho hoạt động không đồng bộ vô dụng. Các tùy chọn của tôi để chạy hoạt động async trong khi vẫn giải phóng luồng giao diện người dùng là gì?Đang chờ thay thế trong .NET 4.0?

+1

sử dụng đang chờ, nhưng theo đúng cách tôi đoán. Bạn có một số mã? – lboshuizen

+3

Có thể chấp nhận sử dụng VS2012 với C# 5.0 trong khi nhắm mục tiêu .net 4.0 không? Xem [Sử dụng async-await on .net 4] (http://stackoverflow.com/questions/9110472/using-async-await-on-net-4) – CodesInChaos

+0

@CodesInChaos Dành cho đồng nghiệp, không :). – Dante

Trả lời

4

Tôi nghĩ tùy chọn cơ bản của bạn là

Cách đơn giản nhất có lẽ là để cài đặt Async CTP. Theo như tôi biết giấy phép cho phép sử dụng comercial. Nó vá các trình biên dịch và đi kèm với một dll 150kb mà bạn có thể đưa vào dự án của bạn.

Bạn có thể sử dụng Task.ContinueWith(). Nhưng điều đó có nghĩa, rằng bạn phải mất một số nỗ lực với xử lý exeption và kiểm soát dòng chảy.

Nhiệm vụ là cấu trúc chức năng. Đó là lý do tại sao ContinueWith() không trộn lẫn với các cấu trúc bắt buộc như các vòng for hoặc try-catch khối. Do đó, asyncawait được giới thiệu để trình biên dịch có thể giúp chúng tôi.

Nếu bạn không thể có sự hỗ trợ của trình biên dịch (tức là bạn sử dụng .Net 4.0), đặt cược tốt nhất của bạn là sử dụng TAP cùng với một khung chức năng. Reactive Extensions là một khuôn khổ rất tốt để điều trị các phương pháp không đồng bộ.

Chỉ cần google cho "nhiệm vụ tiện ích phản hồi" để bắt đầu.

1

Bạn có thể thực hiện một hành vi như await với tiêu chuẩn yield coroutines, tôi đang sử dụng mã này trong mã không phải 4.5. Bạn cần một lớp YieldInstruction được lấy ra từ phương pháp mà nên chạy async:

public abstract class YieldInstruction 
{ 
    public abstract Boolean IsFinished(); 
} 

Sau đó, bạn cần một số hiện thực của YieldInstruction (ae TaskCoroutine mà xử lý một nhiệm vụ) và sử dụng nó theo cách này (Pseudo code):

public IEnumerator<YieldInstruction> DoAsync() 
{ 
    HttpClient client = ....; 
    String result; 
    yield return new TaskCoroutine(() => { result = client.DownloadAsync(); }); 
    // Process result here 
} 

Bây giờ bạn cần một bộ lập lịch xử lý việc thực hiện các hướng dẫn.

for (Coroutine item in coroutines) 
{ 
    if (item.CurrentInstruction.IsFinished()) 
    { 
     // Move to the next instruction and check if coroutine has been finished 
     if (item.MoveNext()) Remove(item); 
    } 
} 

Khi phát triển WPF hoặc WinForms ứng dụng mà bạn cũng có thể để tránh bất kỳ Invoke cuộc gọi nếu bạn đang cập nhật coroutines vào đúng thời điểm. Bạn cũng có thể mở rộng ý tưởng để làm cho cuộc sống của bạn dễ dàng hơn. Ví dụ:

public IEnumerator<YieldInstruction> DoAsync() 
{ 
    HttpClient client = ....; 
    client.DownloadAsync(..); 

    String result; 
    while (client.IsDownloading) 
    { 
     // Update the progress bar 
     progressBar.Value = client.Progress; 
     // Wait one update 
     yield return YieldInstruction.WaitOneUpdate; 
    } 
    // Process result here 
} 
Các vấn đề liên quan