2015-05-26 5 views
1

У меня очень похожий код (я немного упростил код, чтобы продемонстрировать суть поведения, которое я пытаюсь выяснить).Зачем мне нужен этот метод Async?

public async System.Threading.Tasks.Task<bool> IsNumberOdd(int numToTest) 
{ 
    if (numToTest % 2 == 0) 
    { 
     return false; 
    } 
    else 
    { 
     return true; 
    } 
} 

Если я уйду от async на ключевое слово, я получаю жалобы о не в состоянии бросить bool к Task<bool>. Я предполагаю, что здесь присутствует синтаксический сахар. Глядя на IL (я не очень хорошо знаком с IL), похоже, что ключевое слово async вызывает выполнение задачи, а затем возвращаемое значение является результатом задачи. Я правильно понимаю это?

Кстати, если это обман, или если есть какие-то сообщения в блоге, которые обсуждают это, не стесняйтесь указывать на него и закрывать это. Я не пытаюсь пропустить свой репутация; Я пытаюсь понять, что происходит с этим кодом.

EDIT:


Для всех тех, кто спрашивал «почему этот метод асинхронный?» - потому что я пытался построить небольшой и простой пример кода, чтобы продемонстрировать вопрос. Я должен был также добавить пример кода вызова, но я пытался сохранить код как можно малым и простым.

+1

Я думаю, что ответ Джона Скита подходит к вашему вопросу отлично. – slugster

+2

Если нет ничего асинхронного действия, но вам нужно вернуть 'Task ' для подписи, тогда вам может понадобиться 'Task.FromResult (значение T)', то есть 'return Task.FromResult (true);' –

+0

Спасибо @ slugster - именно то, что я хотел знать. Мои навыки в поисковых системах не помогли мне :) –

ответ

4

Я предполагаю, что есть некоторые синтаксический сахар участвует здесь

Не совсем «синтаксический сахар». Компилятор генерирует государственный аппарат, так как метод был отмечен как async. Вот почему вы можете вернуть Task<bool> без явного создания значения Task для возвращаемого значения.

Если я уеду от Асинхронного ключевого слова, я получаю жалобы о невозможности , способных бросить BOOL к Task<bool>.

Модификатор async - это то, что запускает компилятор для создания конечного автомата. Если вы удалите его, вам нужно будет создать Task. Если по какой-либо причине вы хотите создать Task<T>, но вы фактически работаете синхронно, Task.FromResult - ваш друг.

Я не вижу причин, почему этот метод отмечен async.

+1

Я согласен, что этот метод не должен быть асинхронным. Я пытаюсь упростить код, с которым я работаю. –

+0

@OnorioCatenacci Получил ответ на свой вопрос? Я не совсем понял, о чем вы спрашиваете. –

+0

Re. абзац № 2: функция 'async' без какого-либо' ожидания 'будет компилироваться, но с предупреждением. «Async» автоматически обертывает resuilt в 'Task '. – Richard

0

Речь идет не о асинхронном режиме. Его о Задаче.

ваше возвращение логического значения и возвращаемого значения вашей функции Task

 public Task<bool> DoSomething() 
    { 
     return false; 
    } 

также не компилировать. Если вы не выполняете асинхронную операцию, вы не должны возвращать задачу.

Если вам нужно запустить что-то асинхронно, вот несколько вариантов, которые, я надеюсь, сделают использование async/wait clearer.

public class Sample 
{ 
    public async void RunSample() 
    { 
     // return a task. later obtain a result if some fashion 
     Task<bool> task = DoSomethingAsync(); 
     bool res1 = task.Result; 

     // await a task which is created for you by re-wrapping the result. 
     bool res2 = await AwaitSomethingAsync(); 

     // await a task which is created for you by rewrapping the result due to await. 
     bool res3 = await DoSomethingAsync2(); 

     // await a task. 
     bool res4 = await DoSomethingAsync();  
    } 


    public async Task<bool> DoSomethingAsync2() 
    { 
     return false; 
    } 

    public Task<bool> DoSomethingAsync() 
    { 
     return Task<bool>.Run(() => { return false; }); 
    } 

    public async Task<bool> AwaitSomethingAsync() 
    { 
     bool res = await Task<bool>.Run(() => { return false; }); 
     return res; // re-wraps it in a Task 
    } 

} 
+1

Это неверно. Предоставляемый фрагмент кода не будет компилироваться. 'async' - это то, что запускает компилятор для создания государственной машины. –

+0

OP говорит, что он компилируется, когда добавляется 'async' и хочет знать, почему. OP также заявляет, что это упрощенная часть кода для демонстрации проблемы, поэтому вполне вероятно, что в ней нет ничего асинхронного по этому поводу. – juharr

+0

Если вы добавите 'async' к этому коду, он будет компилятором: но с предупреждением, что без' await' он будет работать синхронно. – Richard

2

, кажется, как будто асинхронное ключевое слово вызывает задачу для запуска, а затем возвращаемое значение является результатом задачи

Correct.

В этом методе нет ничего полезного: async. Однако:

Если я уеду от Асинхронного ключевого слова, я получаю жалобы о не в состоянии бросить bool к Task<bool>

будет происходить в вызывающей программе. Не видя этого кода, вы можете только прокомментировать, что вы можете:

  • Измените вызывающего абонента, чтобы он не предполагал, что он получает ожидаемое возвращение.
  • Измените функцию, чтобы вернуть bool, но при использовании вызывающего абонента Task.FromResult(IsNumberOdd(value)).
+1

Упрощенный демонстрационный код, чтобы изолировать поведение, о котором мне было интересно. Да, это изобретательно, а не то, что я бы написал для производственной системы. –

+0

@OnorioCatenacci Без вызывающего абонента невозможно быть конкретным: быть асинхронным является частью договора между вызывающим и вызываемым: они работают вместе. – Richard

Смежные вопросы