2012-09-14 33 views
5

Để chạy mã không đồng bộ (ví dụ như với async/await), tôi cần một Nhiệm vụ phù hợp. Tất nhiên có một số phương pháp được xác định trước trong khuôn khổ bao gồm các hoạt động thường xuyên nhất, nhưng đôi khi tôi muốn viết của riêng tôi. Tôi mới tham gia C# nên rất có thể tôi đã làm sai, nhưng tôi ít nhất cũng không hoàn toàn hài lòng với thực tiễn hiện tại của mình. Xem ví dụ sau đây cho những gì tôi đang làm:Cách viết đúng phương thức trả về tùy chỉnh Tác vụ

public async Task<bool> doHeavyWork() 
    { 
     var b1 = await this.Foo(); 
     //var b2 = await Task<bool>.Factory.StartNew(Bar); //using Task.Run 
     var b2 = await Task.Run(()=>Bar()); 
     return b1 & b2; 
    } 

public Task<bool> Foo() 
    { 
     return Task.Factory.StartNew(() => 
            { 
             //do a lot of work without awaiting 
             //any other Task 
             return false; 
            }); 
    } 

public bool Bar() 
    { 
     //do a lot of work without awaiting any other task 
     return false; 
    } 

Nói chung tôi tạo ra và tiêu thụ các phương pháp như vậy giống như ví dụ Foo, nhưng có một lambda 'thêm' chứa logic phương pháp toàn bộ mà không nhìn imho rất đẹp. Một tùy chọn khác là sử dụng bất kỳ phương thức nào như ví dụ Bar, tuy nhiên tôi nghĩ điều đó thậm chí còn tồi tệ hơn vì không rõ phương thức này nên chạy async (ngoài các tên phương thức thích hợp như BarAsync) và Task.Factory.StartNew có thể phải được lặp lại nhiều lần trong chương trình. Tôi không biết làm thế nào để nói với trình biên dịch ‘phương thức này trả về một nhiệm vụ, hãy quấn nó thành một nhiệm vụ khi được gọi là 'đó là điều tôi muốn làm.

Cuối cùng câu hỏi của tôi: Cách tốt nhất để viết một phương pháp như vậy là gì? Tôi có thể loại bỏ "lambda" phụ (không thêm một phương thức có tên bổ sung)?

EDIT Vì Servy đã cho biết luôn có lý do chính đáng để có phiên bản đồng bộ của phương pháp. Phiên bản async chỉ nên được cung cấp nếu absolutley cần thiết (liên kết của Stephen Cleary).

+0

'" mà không thêm phương thức bổ sung có tên khóa học "' tại sao lại từ chối tùy chọn đó? Tạo 'public bool Bar' và' public Task BarAsync'. – Servy

+0

Tôi muốn tránh chi phí. Nếu nó có ý nghĩa để sử dụng một phương pháp hoặc đồng bộ hoặc không đồng bộ sẽ được sử dụng tốt. Nếu không có một BarAsync công cộng và một Bar riêng (để ẩn nó) và trong trường hợp này tôi không thấy nhiều lý do cho nó. – marce

Trả lời

3

Thế giới sẽ kết thúc nếu ai đó muốn gọi Bar mà không cần khởi động nó trong một chủ đề/Tác vụ mới? Điều gì sẽ xảy ra nếu có một phương thức khác đã có trong một luồng nền nên nó không cần phải bắt đầu một nhiệm vụ mới để chạy mã chạy dài đó? Điều gì sẽ xảy ra nếu phương pháp này kết thúc được tái cấu trúc thành một thư viện lớp được gọi từ cả ngữ cảnh ứng dụng dành cho máy tính để bàn cũng như ngữ cảnh ASP hoặc giao diện điều khiển? Trong những ngữ cảnh khác, phương pháp đó có thể chỉ cần chạy trực tiếp, không phải là Task.

Tôi muốn nói mã của bạn phải giống như Bar ở đó, trừ khi hoàn toàn bắt buộc rằng, trong mọi trường hợp, mã đó sẽ được chạy mà không cần bắt đầu Task mới.

Cũng lưu ý rằng với các phiên bản .NET mới hơn, bạn nên chuyển từ Task.Factory.StartNew sang Task.Run, do đó, số lượng mã sẽ giảm (một chút).

+1

Được rồi, hiểu ý của bạn. Vì vậy, không có 'buộc phương pháp này vào một nhiệm vụ' tính năng bởi vì nó thường là một ý tưởng tồi :) Và nhờ lời gợi ý Task.Run, tôi bằng cách nào đó bị mất nó ... – marce

+3

Cũng thấy: [Tôi có nên phơi bày bộ đóng gói không đồng bộ cho phương pháp đồng bộ? ] (http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx) –

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