async очікують повернення Завдання


131

Чи може хтось пояснити, що це означає в синхронному методі? Якщо я спробую змінити метод, asyncтоді VS скаржиться на це.

Це працює:

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

Це не працює:

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

Тому в основному я хотів би знати, що саме це означає: Task.FromResult<object>(null);



@LB хм, це працює! Але також якщо я просто return;також працює ...!
Девід Дюрі

2
"не працює" не дає дуже хорошого опису того, що не працює. Яке повідомлення про помилку ви отримуєте?
Джон Кернер

@JohnKoerner Я думаю, що цілком очевидно, що компілятор може дати вам таку саму помилку, як якщо б ви намагалися повернути значення у voidфункції.
бінкі

Відповіді:


236

asyncметоди відрізняються від звичайних. Що б ви не повернулися з asyncметодів, загорнуті в Task.

Якщо ви не повернете значення (недійсне), воно буде обгорнуто Task, якщо ви повернете intйого, воно буде загорнуте Task<int>тощо.

Якщо ваш метод асинхронізації потребує повернення, intви позначите тип повернення методу як Task<int>і ви повернетеся intне просто Task<int>. Компілятор перетворить intна Task<int>для вас.

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

Самвей, коли ви повертаєтесь Task<object>, тип повернення вашого методу повинен бутиTask<Task<object>>

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

Оскільки ваш метод повертається Task, він не повинен повертати жодного значення. Інакше він не компілюється.

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

Майте на увазі, що метод асинхронізації без awaitзаяви не є async.


1
Для мене цей тип повернення не працює (я думаю, я роблю щось не так). Приклад статичного завдання асинхронізації <string> DoStuff () {... = очікувати SomeMethodAsync (); повернути "рядкове значення"; } .. var x = DoStuff (); Але це х - з типом "Завдання <рядок>", а не з типом "рядок" ... Чому це так?
Prokurors

3
@Prokurors Також потрібно чекати DoStuff(). Наприклад:var x = await DoStuff();
Sriram Sakthivel

5
Повинно бутиreturn await Task.FromResult<object>(null);
sandeep talabathula

@sandeeptalabathula, що дорівнює нулю,
Sriram Sakthivel

2
@ProfK Task.WhenAny- приклад.
Сервіс

55

Вам потрібно використовувати ключове слово очікування під час використання async, а тип повернення функції має бути загальним. Ось приклад із значенням повернення:

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

Ось приклад без зворотного значення:

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

Прочитайте ці:

TPL: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx та завдання: http://msdn.microsoft.com/en-us/library/system.threading .задачі (v = vs.110) .aspx

Async: http://msdn.microsoft.com/en-us/library/hh156513.aspx Чекайте: http://msdn.microsoft.com/en-us/library/hh156528.aspx


9
Ви можете просто повернутися nullбезпосередньо, а не чекати завдання на манекен.
Лі

5
@Lee, але якщо ви це зробите, компілятор скаржиться (дає попередження), що asyncметод буде виконувати асинхронно із пропозицією використовувати awaitключове слово десь у методі. Я пропоную просто використовувати return Task.FromResult((object)null);та видалити asyncключове слово, щоб зменшити попереджувальний шум компілятора.
бінкі

Так, я спробував просто використовувати returnв завданні, але завдання продовжує виконувати, тому що returnне повертається aTask
Тернер Бас

30

Додавання ключового слова async - це лише синтаксичний цукор для спрощення створення державної машини. По суті, компілятор приймає ваш код;

public async Task MethodName()
{
     return null;
}

І перетворює це на;

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

Якщо у вашому коді є якісь awaitключові слова, компілятор повинен прийняти ваш метод і перетворити його в клас для представлення стану машини, необхідної для його виконання. У кожному awaitключовому слові стан змінних та стек будуть збережені в полях класу, клас додасть себе як гачок завершення до завдання, яке вас чекає, а потім повернеться.

Коли це завдання буде виконано, ваше завдання буде виконано знову. Тож додатковий код додається у верхній частині методу для відновлення стану змінних і переходу до наступної таблиці вашого коду.

Дивіться, що створює асинхроніка та очікування? на приклад горі.

Цей процес має багато спільного з тим, як компілятор обробляє ітераторні методи із заявами про вихід.


2

Це завдання, яке повертає завдання типу String (анонімна функція C # або іншим словом, делегація використовується "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
Розміщуючи код як відповідь, будь-ласка, додайте пояснення того, що ви демонструєте. У цьому випадку ви додаєте відповідь на старе запитання, на яке вже є кілька відповідей. Будь ласка, додайте речення або два, що описують, що демонструє ваша нова відповідь, що ще не було показано в інших відповідях. Я не кажу, що у вашій відповіді нічого поганого, я просто прошу допомогти іншим, склавши слова, що ви показуєте зі своїм кодом.
ToolmakerSteve

0

Щоб отримати відповідні відповіді від методів асинхронізації, вам потрібно зачекати під час виклику цих методів завдання. Це зачекає перетворення його назад у тип повернутого значення, а не у тип завдання.

Напр. Зміст = очікуйте StringAsyncTask (

де загальнодоступне завдання асинхронізації < Рядок > StringAsyncTask ())

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.