Async Framework TaskEx.Delay проблема - PullRequest
1 голос
/ 02 июня 2011

Я обнаружил какую-то проблему при вызове TaskEx.Delay с Async Framework CTP в C #

public async Task<string> TestAsync() {
    return await TaskEx.RunEx<string>( async () => { //in real app this is time consuming code so this line is so complex 
            await TaskEx.Delay( 1000 );
            return "test;
        } );
}

public async void Test {
    var count = 0;
    while( count < 100 ) {
        var val = await TestAsync();
        Console.WriteLine( val ); // in real app this line adds elements to observable collection binded to ListBox
        count++;
    }
}

Вывод на консоль появляется в основном один раз (иногда два или три раза), но не 100 раз, как я ожидал.

EDIT:

Это не консольное приложение (приведенный выше код упрощен), это приложение WP7. Без использования задержки все работает нормально.

Ответы [ 2 ]

2 голосов
/ 02 июня 2011

Это потому, что метод Test действительно и действительно является асинхронным методом. Компилятор C # просто позволяет скрыть это, имея тип возврата void. Так что если ваш основной метод выглядит следующим образом

public static void Main() {
  Test();
}

Тогда он на самом деле не работает Test и ожидает его полного завершения. Вместо этого он действительно планирует Test для запуска, и его завершение произойдет в какой-то момент в будущем. Так что имеет смысл, что вы видите разные результаты, потому что это связано со временем.

2 голосов
/ 02 июня 2011

Вероятно, это связано с тем, что вы работаете в консольном приложении, а не в приложении Windows.

Асинхронное поведение в консольном приложении отличается от поведения в Windows Forms, WPF илиПриложение WCF, поскольку отсутствует контекст синхронизации.Таким образом, await отправляет сообщения обратно в поток пула потоков и фактически не «ожидает» выполнения.

Если вы запустите это в приложении WPF или Windows Forms, оно будет вести себя как положено.


Кстати, ваш метод слишком сложен.Вы можете просто сделать:

public async Task<string> TestAsync() {
    await TaskEx.Delay( 1000 );
    return "test";
}

Это будет эффективно работать так же, как ваш предыдущий метод, но с гораздо меньшими накладными расходами (и гораздо проще).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...