Api профилирования .NET — вычисляет время, необходимое для выполнения асинхронного метода

#async-await #clr-profiling-api #clrprofiler

Вопрос:

Для мониторинга моего основного приложения dotnet, которое я использую .Api профилирования NET clr позволяет отслеживать уровень метода и вычислять время, необходимое любому методу для завершения его выполнения. Я не могу получить время, затраченное асинхронными методами.

 public ActionResult<IEnumerable<string>> Get()
    {
        Ok(RunQueryAsync().Result);
        return new string[] { "value1", "value2" };
    }
public async Task<String> RunQueryAsync()
    {
                // in the PostDataAsyncWithHeader I'm making async api request using HttpClient
                await PostDataAsyncWithHeader();
        }
        catch (Exception ex)
        {
            //display error message
            return "Exception: "   ex.Message;
        }
    }
 

В приведенном выше коде я делаю запрос api из метода PostDataAsyncWithHeader (), выполнение которого занимает почти 5 секунд. Но когда я использую крючки ввода и выхода профилирования clr для вычисления времени, метод Get() показывает около 5 секунд, но методы RunQueryAsync() и PostDataAsyncWithHeader() показывают 0 мс. Но фактическое время занимает метод PostDataAsyncWithHeader().

Я хочу найти точное время, затраченное методом PostDataAsyncWithHeader (). Пожалуйста, подскажите мне, как я могу этого достичь.

Ответ №1:

Среда clr не знает асинхронных методов, компилятор преобразует их в обычные методы и конечный автомат. Что касается среды RunQueryAsync выполнения, то это простой метод, который создаст конечный автомат и вызовет его MoveNext метод. Это приведет к запуску тела асинхронного метода до тех пор, пока первое ожидание не завершится синхронно, а затем оно вернется с Task объектом.

Get С другой стороны, ваш метод не является асинхронным методом, когда он вызывает Task<string>.Result блоки, ожидающие завершения возвращаемой задачи RunQueryAsync .

Определение того , когда асинхронный метод завершен, вероятно, будет означать ожидание возврата MoveNext метода на государственной машине и проверку того, что государственная машина находится в состоянии «завершено» (я обычно нахожу, что государственная машина считается завершенной, когда состояние есть -2 , но я бы не ожидал, что это будет договорным).