async đang chờ nhiệm vụ trở lại


131

Ai đó có thể giải thích điều này có nghĩa là gì trong một phương pháp đồng bộ? Nếu tôi cố gắng thay đổi phương thức để asyncVS phàn nàn về nó.

Những công việc này:

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

Điều này không hoạt động:

public async Task MethodName()
{
     return Task.FromResult<object>(null);
}

Vì vậy, về cơ bản tôi muốn biết chính xác điều này có nghĩa là gì: Task.FromResult<object>(null);



@LB hmm mà hoạt động! Nhưng nếu tôi cũng return;làm việc thì ...!
David Dury

2
"không hoạt động" không cung cấp một mô tả rất tốt về những gì không hoạt động. Thông báo lỗi bạn nhận được là gì?
John Koerner

@JohnKoerner Tôi nghĩ khá rõ ràng rằng trình biên dịch có thể gây ra lỗi tương tự như khi bạn cố trả về một giá trị trong voidhàm.
biley

Câu trả lời:


236

asyncphương pháp khác với phương pháp bình thường. Bất cứ điều gì bạn trở về từ asynccác phương thức đều được gói trong mộtTask .

Nếu bạn trả lại không có giá trị (void), nó sẽ được bọc lại Task, Nếu bạn trả lại, intnó sẽ được bọc Task<int>và cứ thế.

Nếu phương thức không đồng bộ của bạn cần trả về, intbạn sẽ đánh dấu loại trả về của phương thức Task<int>và bạn sẽ trả về đơn giản intkhông phải là Task<int>. Trình biên dịch sẽ chuyển đổi intthành Task<int>cho bạn.

private async Task<int> MethodName()
{
    await SomethingAsync();
    return 42;//Note we return int not Task<int> and that compiles
}

Sameway, Khi bạn trả về kiểu trả về Task<object>của phương thức của bạn sẽ làTask<Task<object>>

public async Task<Task<object>> MethodName()
{
     return Task.FromResult<object>(null);//This will compile
}

Vì phương thức của bạn đang trả về Task, nên nó không trả về bất kỳ giá trị nào. Nếu không nó sẽ không biên dịch.

public async Task MethodName()
{
     return;//This should work but return is redundant and also method is useless.
}

Hãy nhớ rằng phương pháp async mà không có awaitcâu lệnh là không async.


1
Đối với tôi kiểu trả về này không hoạt động (tôi đoán tôi đang làm gì đó sai). Ví dụ Nhiệm vụ async tĩnh <chuỗi> DoStuff () {... = đang chờ someMethodAsync (); trả về "giá trị chuỗi"; } .. var x = DoStuff (); Nhưng x - này là với loại "Nhiệm vụ <chuỗi>", không phải với loại "chuỗi" ... Tại sao lại như vậy?
Prokurors 9/2/2015

3
@Prokurors Bạn cũng cần chờ DoStuff(). Ví dụ:var x = await DoStuff();
Sriram Sakth Xoay

5
Nên làreturn await Task.FromResult<object>(null);
sandeep Talabathula

@sandeeptalabathula tương đương với trả về null
Sriram

2
@ProfK Task.WhenAnylà một ví dụ.
Phục vụ

55

Bạn cần sử dụng từ khóa await khi sử dụng async và loại trả về hàm của bạn phải chung chung Dưới đây là một ví dụ với giá trị trả về:

public async Task<object> MethodName()
{
    return await Task.FromResult<object>(null);
}

Đây là một ví dụ không có giá trị trả về:

public async Task MethodName()
{
    await Task.CompletedTask;
}

Đọc những thứ này:

TPL: http://msdn.microsoft.com/en-us/l Library / dd460717 ( v = vs.110) .aspx và Nhiệm vụ: http://msdn.microsoft.com/en-us/l Library / system.threading .t nhiệm vụ (v = vs.110) .aspx

Async: http://msdn.microsoft.com/en-us/l Library / hh156513.aspx Đang chờ: http://msdn.microsoft.com/en-us/l Library / hh156528.aspx


9
Bạn chỉ có thể quay lại nulltrực tiếp thay vì chờ đợi một nhiệm vụ giả.
Lee

5
@Lee, nhưng nếu bạn làm điều đó, trình biên dịch sẽ phàn nàn (đưa ra cảnh báo) rằng asyncphương thức sẽ thực thi không đồng bộ với một đề xuất sử dụng awaittừ khóa ở đâu đó trong phương thức. Tôi đề nghị chỉ sử dụng return Task.FromResult((object)null);và loại bỏ asynctừ khóa để giảm tiếng ồn cảnh báo trình biên dịch.
biley

Có, tôi đã thử chỉ sử dụng returntrong Tác vụ, nhưng tác vụ vẫn tiếp tục thực thi, vì returnkhông trả vềTask
Turner Bass

30

Thêm từ khóa async chỉ là đường cú pháp để đơn giản hóa việc tạo ra một máy trạng thái. Về bản chất, trình biên dịch lấy mã của bạn;

public async Task MethodName()
{
     return null;
}

Và biến nó thành;

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

Nếu mã của bạn có bất kỳ awaittừ khóa nào , trình biên dịch phải lấy phương thức của bạn và biến nó thành một lớp để thể hiện máy trạng thái cần thiết để thực thi nó. Tại mỗiawait từ khóa, trạng thái của các biến và ngăn xếp sẽ được bảo toàn trong các trường của lớp, lớp sẽ tự thêm vào như một cái móc hoàn thành cho nhiệm vụ bạn đang chờ, sau đó quay trở lại.

Khi nhiệm vụ đó hoàn thành, nhiệm vụ của bạn sẽ được thực hiện lại. Vì vậy, một số mã bổ sung được thêm vào đầu phương thức để khôi phục trạng thái của các biến và nhảy vào bản tiếp theo của mã của bạn.

Xem Async & await tạo gì?cho một ví dụ đẫm máu.

Quá trình này có nhiều điểm chung với cách trình biên dịch xử lý các phương thức lặp với các câu lệnh lợi tức.


2

Đây là một Tác vụ đang trả về một Chuỗi loại Nhiệm vụ (hàm ẩn danh C # hoặc nói cách khác, một ủy nhiệm được sử dụng 'Func')

    public static async Task<string> MyTask()
    {
        //C# anonymous AsyncTask
        return await Task.FromResult<string>(((Func<string>)(() =>
        {
            // your code here
            return  "string result here";

        }))());
    }

1
Khi đăng mã dưới dạng câu trả lời, vui lòng bao gồm một số giải thích về những gì bạn đang thể hiện. Trong trường hợp này, bạn đang thêm một câu trả lời cho một câu hỏi cũ đã có một vài câu trả lời. Vui lòng thêm một hoặc hai câu mô tả câu trả lời mới của bạn đang thể hiện điều gì, điều đó chưa được thể hiện trong các câu trả lời khác. Tôi không nói bất cứ điều gì sai với câu trả lời của bạn, chỉ yêu cầu bạn giúp đỡ người khác bằng cách nói ra những gì bạn đang hiển thị với mã của mình.
ToolmakerSteve

0

Để nhận được phản hồi thích hợp trở lại từ các phương thức không đồng bộ, bạn cần phải chờ trong khi gọi các phương thức tác vụ đó. Điều đó sẽ chờ chuyển đổi nó trở lại loại giá trị được trả về chứ không phải loại nhiệm vụ.

Ví dụ: var content = đang chờ StringAsyncTask (

trong đó Nhiệm vụ async công khai < String > StringAsyncTask ())

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.