механизм асинхронного ожидания / ожидания в C # - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть 2 вопроса, которые я хотел бы задать.

  1. Я прочитал этот абзац в документах Microsoft об async / await. Но я не поняла это ясно.

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/task-asynchronous-programming-model#BKMK_APIAsyncMethods

"Если GetStringAsync (и, следовательно, getStringTask) завершается до того, как AccessTheWebAsync его ожидает, элемент управления остается в AccessTheWebAsync. Расходы на приостановку и последующий возврат к AccessTheWebAsync будут потрачены впустую, если вызываемый асинхронный процесс (getStringTask) уже завершен и AccessTheWebync не завершен придется ждать окончательного результата. "

Не могли бы вы объяснить это?

  1. Как я читал, когда вы используете async / await в C #, код не выполняется в двух отдельных потоках. Он по-прежнему находится в синхронном контексте, но вернет Task в случае, если он встретит ключевое слово «await» в качестве обещания, что результат будет возвращен до его завершения. Если задача завершается до «ожидания», то теперь она аналогична синхронной. Нет отличий Даже дорого переключаться с метода вызывающего на метод AccessTheWebAsync и наоборот.

Извините, я впервые задаю вопросы о StackOverflow.

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

С учетом функции:

async Task<int> AccessTheWebAsync()  
{   
    // You need to add a reference to System.Net.Http to declare client.  
    using (HttpClient client = new HttpClient())  
    {  
        Task<string> getStringTask = client.GetStringAsync("https://docs.microsoft.com");  

        DoIndependentWork();  

        string urlContents = await getStringTask;  

        return urlContents.Length;  
    }  
}   

Когда выполнение достигает

string urlContents = await getStringTask; 

, выполнение может выполнять одно из двух действий:

  1. If GetStringAsync () уже завершено, выполнение продолжается со следующей строки (return urlContents.Length;)
  2. Если GetStringAsync () не завершена, выполнение AccessTheWebAsync () приостанавливается и выполнение возвращается к вызывающей функции до тех пор, пока GetStringAsync не вернется к вызывающей функции.() завершается.В параграфе, о котором вы спрашиваете, говорится, что если мы в любом случае приостановим выполнение AccessTheWebAsync (), затраты на приостановку и последующий возврат к AccessTheWebAsync будут потрачены впустую. Поэтому этого не произойдет, поскольку это достаточно умнознать, когда приостановить исполнение, а когда нет.
0 голосов
/ 02 апреля 2019

Асинхронный метод в C # всегда должен возвращать задачу и выглядит следующим образом:

public async Task method();
public async Task<bool> asyncMethod();

Когда он ничего не возвращает, поэтому void просто возвращает Task и в любом другом случае Task<returntype>

Когда вы вызываете асинхронный метод, вы можете сделать 3 вещи:

// Result is now of type Task<object> and will run async with any code beyond this line.
// So using result in the code might result in it still being null or false.
var result = asyncMethod();

// Result is now type object, and any code below this line will wait for this to be executed.
// However the method that contains this code, must now also be async.
var result = await asyncMethod();

// Result is now type Task<object>, but result is bool, any code below this line will wait.
// The method with this code does not require to be async.
var result = asyncMethod().Result;

Таким образом, чтобы ответить на ваши вопросы.

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

То же самое происходит и в обратном направлении: при ожидании метода, который ничего не возвращает, ожидание обычно не требуется.

...