Элинирование async / ожидание внутри Task.Run [duplicate]

Как отметил @FelixKling, наиболее вероятным сценарием является то, что узлы, которые вы ищете, еще не существуют.

Однако современные методы разработки часто могут манипулировать элементами документа за пределами дерева документов либо с DocumentFragments, либо просто отсоединением / повторным подключением текущих элементов напрямую. Такие методы могут использоваться как часть шаблонов JavaScript или для предотвращения чрезмерных операций перерисовки / переплавки, в то время как элементы, о которых идет речь, сильно изменяются.

Аналогично, новая функциональность «Теневой DOM» развертывается в современных браузерах позволяет элементам быть частью документа, но не обрабатываться запросом document.getElementById и всеми его методами sibling (querySelector и т. д.). Это делается для инкапсуляции функциональных возможностей и, в частности, скрыть его.

Опять же, скорее всего, элемент, который вы ищете, просто (пока) в документе, и вы должны сделать, как предлагает Феликс , Тем не менее, вы также должны знать, что это все чаще является не единственной причиной того, что элемент может быть необоснованным (временно или постоянно).

32
задан Jay Bazuzi 26 July 2013 в 17:58
поделиться

2 ответа

Вы не можете вернуть задачу, если сам метод объявлен как async - поэтому это не будет работать, например:

async Task BarAsync()
{
    return BazAsync(); // Invalid!
}

Для этого потребуется тип возврата Task<Task>.

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

Это также общий шаблон для внедрение перегрузки, например маркером отмены.

Просто имейте в виду, что если вам нужно перейти на ожидание чего-то другого, вам нужно сделать его асинхронным. Например:

// Version 1:
Task BarAsync()
{
    // No need to gronkle yet...
    return BazAsync();
}

// Oops, for version 2 I need to do some more work...
async Task BarAsync()
{
    int gronkle = await GronkleAsync();
    // Do something with gronkle

    // Now we have to await BazAsync as we're now in an async method
    await BazAsync();
}
31
ответ дан Jon Skeet 20 August 2018 в 09:48
поделиться
  • 1
    If your method is just doing a small amount of work and then calling just one async method В частности, это общий шаблон для перегрузки async методов (например, BarAsync() и BarAsync(CancellationToken)). – Stephen Cleary 26 July 2013 в 18:09
  • 2
    @StephenCleary: Действительно - и аналогично проверяется синхронно с последующим возвратом "реального" асинхронная задача. Будет редактировать, чтобы указать это. – Jon Skeet 26 July 2013 в 18:12
  • 3
    @JonSkeet, извините за возрождение этого через 3 года, но вопрос - всякий раз, когда я вижу код, который не имеет await и просто возвращает Task, если в этой задаче есть исключение, иногда кажется, что он «исчезает», , даже если вызывающий абонент ожидает выполнения этой задачи. Будет ли это связано с вашим комментарием об исключении синхронного исключения? – Cody 11 August 2016 в 14:32
  • 4
    @Cody: Нет, исключение не исчезает. Я предлагаю вам задать новый вопрос, в котором подробно описывается ваша ситуация. – Jon Skeet 11 August 2016 в 22:06

Проверьте эту ссылку, где описано: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx

async Task<int> TaskOfTResult_MethodAsync()
{
    int hours;
    // . . .
    // The body of the method should contain one or more await expressions.

    // Return statement specifies an integer result.
    return hours;
}

    // Calls to TaskOfTResult_MethodAsync from another async method.
private async void CallTaskTButton_Click(object sender, RoutedEventArgs e)
{
    Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync();
    int intResult = await returnedTaskTResult;
    // or, in a single statement
    //int intResult = await TaskOfTResult_MethodAsync();
}






// Signature specifies Task
async Task Task_MethodAsync()
{
    // . . .
    // The body of the method should contain one or more await expressions.

    // The method has no return statement.  
}

    // Calls to Task_MethodAsync from another async method.
private async void CallTaskButton_Click(object sender, RoutedEventArgs e)
{
    Task returnedTask = Task_MethodAsync();
    await returnedTask;
    // or, in a single statement
    //await Task_MethodAsync();
}
2
ответ дан Kees de Wit 20 August 2018 в 09:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: