Eliding async и ожидающий поток - PullRequest
0 голосов
/ 19 сентября 2019

В статье о элиминации асинхронного ожидания есть следующий пример:

public Task<string> GetElidingKeywordsAsync(string url)
{
    using (var client = new HttpClient())
        return client.GetStringAsync(url);
}

И он описал поток следующим образом:

С GetElidingKeywordsAsync код делает это:

  1. Создайте объект HttpClient.

  2. Вызвать GetStringAsync, который возвращает незавершенную задачу.

  3. Удаляет объект HttpClient.

  4. Возвращает задачу, которая была возвращена из GetStringAsync.

Почему поток не выглядит следующим образом?

  1. Создайте объект HttpClient.

  2. Удаляет объект HttpClient.

  3. Вызывает GetStringAsync и возвращает задачу, возвращенную из GetStringAsync.

Ответы [ 2 ]

4 голосов
/ 19 сентября 2019

Использование блока без фигурных скобок или точки с запятой имеет подразумеваемое тело:

public Task<string> GetElidingKeywordsAsync(string url)
{
    using (var client = new HttpClient())
        return client.GetStringAsync(url); // using body
}

Это может быть нормализовано до:

public Task<string> GetElidingKeywordsAsync(string url)
{
    using (var client = new HttpClient())
    {
        return client.GetStringAsync(url);
    }
}

Или записано более компактно в C # 8.0:

public Task<string> GetElidingKeywordsAsync(string url)
{
    using var client = new HttpClient();
    return client.GetStringAsync(url);
}

Если вы добавите точку с запятой, будет пустое тело, дающее поведение, описанное вами в OP:

public Task<string> GetElidingKeywordsAsync(string url)
{
    HttpClient client;
    using (client = new HttpClient());  // gets disposed before next statement
        return client.GetStringAsync(url);  // don't be fooled by the indent
}

Это можно нормализовать до:

public Task<string> GetElidingKeywordsAsync(string url)
{
    HttpClient client;
    using (client = new HttpClient())
    {
    }
    return client.GetStringAsync(url);
}
2 голосов
/ 19 сентября 2019

Расширяя комментарий, приведенный выше, было бы полезно, если бы вы увидели, как работает метод GetStringAsync.

Предполагая, что в качестве метода aysnc используется следующее:

public async Task<string> GetMethodAsync(string url)
{
    // perform some operations

    // execution will pause here due to await statement 
    // after calling download URL and the Task will be returned
    var result = await DownloadURL(string);

    //perform some more function
    // finally return the result
    return result;
}

Примечание здесьвызов метода к DownloadURL будет выполнен, и тогда только выполнение будет приостановлено, чтобы дождаться возвращения результатов, и будет возвращено task.Создание метода Async само по себе не дает отложенного выполнения, а только часть после вызова await становится «отложенной».

По этой причине вы получите незавершенное задание, а затем на следующем этапе клиент будет ликвидирован.

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