2012-07-17 26 views
9

Với phương pháp sau đây:chờ AsyncMethod() so với chờ đợi Task.Factory.StartNew <TResult> (AsyncMethod)

public async Task<MyObject> DoSomethingAsync() { 
    // do some work 
    await OpenSomeFileAsync(); 
    return new MyObject(); 
} 

Có một sự khác biệt giữa:

public async void SomeEventHandler(EventArgs args) { 
    var myObject = await await Task.Factory.StartNew<Task<MyObject>>(DoSomethingAsync); 
    // do something with myObject 
} 

và:

public async void SomeEventHandler(EventArgs args) { 
    var myObject = await DoSomethingAsync(); 
    // do something with myObject 
} 

Tôi đã nghĩ rằng phần "làm một số công việc" của DoSomethingAsync sẽ xảy ra ngay lập tức trong một tác vụ mới trong trường hợp đầu tiên, nhưng thành thật mà nói tôi không thực sự hiểu đầy đủ về cách Nhiệm vụ, không đồng bộ và đang chờ đợi đang làm việc, và tôi khá chắc chắn rằng tôi chỉ là những điều quá phức tạp cho bản thân mình.

EDIT:

Câu hỏi này đến khoảng từ nhìn vào ví dụ này Metro: http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782

Cụ thể trong MainPage.xaml.cs, họ có điều này:

var unused = Task.Factory.StartNew(async() => { // some work... }); 
// unused is of type Task<TResult> 

Tôi đã cố gắng để rework nó mà không cần sử dụng một chức năng async nặc danh và tôi bắt đầu tự hỏi, tại sao không chỉ viết một phương thức async và chờ nó, thay vì gọi StartNew và bàn giao trong một hàm async?

+0

Tại sao bạn sẽ muốn viết nó ra như vậy? Toàn bộ điểm sử dụng từ khóa 'async'/'await' mới là để bạn không phải làm như vậy. –

+0

Dường như một đoạn mã ví dụ không hợp lệ của số điện thoại –

+0

Tôi chỉ xem bản thân mình và ... Wow. Vâng, đó là "chính thức Windows SDK mẫu" mã là ** thực sự xấu **! Tôi nghĩ họ đã hoàn toàn bỏ lỡ điểm 'không đồng ý'! –

Trả lời

11

Hầu hết thời gian, thêm Task khác không hữu ích, nhưng trong một số trường hợp, có thể.

Sự khác biệt là nếu bạn đang ở trên chuỗi giao diện người dùng (hoặc tương tự) và thực thi trực tiếp DoSomethingAsync(), phần đầu tiên (// do some work) cũng sẽ thực hiện trên chuỗi giao diện người dùng. họ sử dụng ConfigureAwait()). Mặt khác, nếu bạn bắt đầu một Task khác, cả phần đầu tiên và bất kỳ phần nào sau đây của DoSomethingAsync() sẽ thực hiện trên ThreadPool.

Nếu DoSomethingAsync() được viết chính xác, hãy thêm Task sẽ không cung cấp cho bạn bất kỳ lợi thế nào (và sẽ cho bạn bất lợi về chi phí cao hơn), nhưng tôi có thể tưởng tượng có trường hợp sẽ tạo sự khác biệt.

Ngoài ra, thay vì sử dụng Task.Factory.StartNew() và hai await s, bạn có thể viết:

await Task.Run(DoSomethingAsync); 
+1

Điểm tốt, tôi không nghĩ về phần trước khi chờ đợi ... +1 –

+0

Câu trả lời rất hay, cảm ơn mọi người đã trả lời! –

4

Có, có sự khác biệt: ở dạng đầu tiên, bạn có thêm một cấp nhiệm vụ, điều này hoàn toàn không hữu ích.

Các hình thức đầu tiên về cơ bản là tương đương với điều này:

Task<Task<MyObject>> task1 = Task.Factory.StartNew<Task<MyObject>>(DoSomethingAsync); 
Task<MyObject>> task2 = await task1; 
var myObject = await task2; 

Vì vậy, nó không thực sự có ý nghĩa: bạn đang tạo một nhiệm vụ mà chỉ ... tạo ra công việc khác.

+0

Cảm ơn phản hồi - Tôi đã suy nghĩ nhiều.Nếu bạn có thời gian, bạn có thể giải quyết chỉnh sửa của mình không? Tôi bị nhầm lẫn bởi cách tiếp cận được đưa ra trong ví dụ mà tôi đang xem ... –

+0

AFAICT, đó là một ví dụ xấu –

+0

@justin, tôi đồng ý với James, đó là một ví dụ thực sự tồi tệ ... không có lý do gì để tạo nhiệm vụ trên một phương pháp async, vì nó đã trả về một nhiệm vụ –

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