2013-12-02 3 views
1

Есть некоторые вещи, о Асинхронный-ЖДИТЕ, что только мистифицировать меня, и мне было интересно, если кто-то может что-то объяснить мне:Асинхронный-поджидают запросы Ключевое слово

Просто к сведению, мои запросы приходят после прочтения этого: http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspx

Так Эрик Липперт говорит

«асинхронной» модификатор на методе не означает, что «этот метод автоматически планируется запустить на рабочем потоке асинхронно»

Почему мы должны PLAC e Async для методов, которые мы хотим запустить асинхронно? т.е.

private async Task<int> GetMeInt() 
{ 
    return 0; 
} 
private async void stuff() 
{ 
    var num = GetMeInt(); 
    DoStuff(); 
    int end = await num; 
    for (int i = 0; i < end; i++) 
     Console.WriteLine("blahblahblah"); 
} 

Дело в том, что мы не хотим GetMeInt на самом деле сделать что-нибудь асинхронной внутренне. Мы просто хотим, чтобы он запускался синхронно, но мы хотим, чтобы он выполнялся асинхронно в целом при вызове другим методом. Мне кажется более разумным поставить асинхронный метод только на метод Stuff() и разрешить GetMeInt() работать в другом потоке и возвращаться позже.

По существу я считаю, что это будет что-то вроде такого:

private int GetMeInt() 
{ 
    return 0; 
} 

private async void stuff() 
{ 
    int? num = null; 
    Thread t = new Thread(() => num = GetMeInt()); 
    t.Start(); 
    DoStuff(); 
    t.Join(); 
    for (int i = 0; i < (num??0); i++) 
     Console.WriteLine("blahblahblah"); 
} 

В конце концов, это не государственная машина создается только на методе Материала()? Что делает его более запутанным, так это то, что компилятор дает предупреждение, если я помещаю async в GetMeInt, его не очень приятно принудительно переносить все, что возвращается GetMeInt() в объект задачи, и этот тип вещей мешает нам используя методы, которые кто-то написал асинхронно.

Почему они не спроектировали его таким образом, чтобы вы могли сделать что-то подобное (это территория непроверенного теоретического кода!). Я бы предположил, что есть причины, связанные с фреймворком, но я думаю, что такая вещь будет более интуитивной. Я пропустил что-то очевидное в этом асинхронном бизнесе? Должен ли я просто игнорировать предупреждение и идти вперед, мой OCD просто не позволит этому уйти.

private async void stuff() 
{ 
    var s = Example.Run<int>(Delegate.CreateDelegate(typeof(Delegate), this, "GetMeInt")); 
    DoStuff(); 
    for (int i = 0; i < s.Result; i++) 
     Console.WriteLine("blahblahblah"); 
} 

public class Example 
{ 
    Thread t; 
    Object r; 
    private Example(){} 
    public static Example<T> Run<T>(Delegate pFunc) 
    { 
     Example<T> output = new Example<T>(); 
     output.t = new Thread(() => output.r = (T)pFunc.DynamicInvoke()); 
     output.t.Start(); 
     return output; 
    } 

    public sealed class Example<T> : Example 
    { 

     public T Result 
     { 
      get 
      { 
       t.Join(); 
       return (T)r; 
      } 
      private set; 
     } 
    } 
} 

Я действительно не понимаю, любое объяснение по этому поводу было бы оценено.

+1

Вы полностью недооцениваете ключевое слово 'async'; предупреждение компилятора абсолютно корректно. Вы ищете 'Task.Run()'. – SLaks

+4

@Aelphaeis: «Асинхронный» делает * not * означает «работает на фоновом потоке». * Асинхронный * просто означает, что операция начинается и независимо завершается в более позднее время, в течение которой ваш поток может свободно выполнять другие вещи. –

+0

@ Stephen Теперь я действительно смущен. Если операция независима, это означает, что они могут работать параллельно друг с другом. Разве это не точка многопоточности и Async как парадигма? Что мне не хватает? – Aelphaeis

ответ

5

Все модификатор async означает, что этот способ способен await вещей.

Поскольку компилятор предупреждает вас, он абсолютно бесполезен, если у вас на самом деле нет чего-то await.

Вы действительно спрашиваете, как выполнять работу над фоновым потоком, а затем асинхронно дожидаться завершения.
Вы можете использовать Task.Run() для запуска кода в фоновом режиме, затем await результирующая задача.

+0

в порядке, поэтому если Task.Run() используется для параллельной работы, что ожидает/async? Выполняют ли они одну и ту же цель? – Aelphaeis

+1

@Aelphaeis: Совсем нет. 'Task.Run()' запускает код в фоновом режиме. 'await' ждет завершения любой текущей операции. – SLaks

0

Ключевое значение для понимания async заключается в том, что, строго говоря, метод возвращается до завершения его работы. Это, по сути, единственное, что означает ключевое слово. Ваш пример, который сразу возвращает 0, не выполняет эту «разгрузку», поэтому компилятор предупреждает вас о том, что в ней нет смысла использовать async.

Именно поэтому методы async должны возвращать Task<T> (так что вы можете определить, когда работа метода действительно завершена, и принять меры в отношении теперь доступного результата), и именно поэтому все, что использует ожидание, должно быть асинхронным (поскольку теперь этот внешний метод будет также возврат перед «сделано»).

+0

Вы не обращаетесь к его первому недоразумению. – SLaks

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