Могут ли асинхронные методы иметь дорогой код перед первым «ожиданием»? - PullRequest
9 голосов
/ 09 декабря 2011

Плохо ли иметь дорогой код в начале асинхронного метода до вызова первого await?Должен ли этот код быть добавлен вместо TaskEx.Run?

public async Task Foo()
{
    // Do some initial expensive stuff.
    // ...

    // First call to an async method with await.
    await DoSomethingAsync;
}

Ответы [ 2 ]

10 голосов
/ 09 декабря 2011

Как говорит Рид, это действительно зависит от контекста. Код должен выполняться с некоторой точкой - но в зависимости от контекста он может в конечном итоге выполняться в потоке пула потоков, а не в каком-то критическом.

Вместо использования Task.Run я бы использовал TaskEx.Yield:

public async Task Foo()
{
    await TaskEx.Yield();
    // Do expensive stuff
}

Насколько я знаю, это в основном способ немедленного возврата к вызывающей стороне, но позволяет сразу запланировать оставшуюся часть асинхронного метода. Если вы находитесь в чем-то вроде потока пользовательского интерфейса Windows Forms, нет смысла делать это, поскольку вы сразу же вернетесь к потоку пользовательского интерфейса (и выполняете там дорогой код) - но это будет иметь смысл, если вы находитесь в контексте где текущий поток не должен быть заблокирован, но продолжения выполняются в другом потоке.

5 голосов
/ 09 декабря 2011

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

Если возможно, я бы порекомендовал стараться иметь как можно меньше «дорогого» кода, ведущего к первому ожиданию. Использование Task.Run (или TaskEx.Run в CTP) для переноса дорогого кода или перемещение дорогого кода в собственный асинхронный метод (на котором вы могли бы await) было бы полезно в этом случае.

...