Я не понимаю, что делает этот код

Я относительно новичок в C#. Может кто-нибудь объяснить, что здесь происходит?

public List<InboundPlanSummary> GetListInboundPlans(ParameterGetListInboundPlans parameterGetListInboundPlans) =>
    Task.Run(() => GetListInboundPlansAsync(parameterGetListInboundPlans)).ConfigureAwait(false).GetAwaiter().GetResult();

Я потерялся здесь. Любая помощь с объяснением будет принята с благодарностью.

=> — это лямбда-оператор, который в основном читается как «дано что-то, верните что-то» stackoverflow.com/questions/290061/…. Я предполагаю, что приведенная выше команда настраивает задачу, которая принимает список входящих планов и в конечном итоге возвращает результаты асинхронно.

Bart McEndree 31.05.2024 13:57

Похоже на попытку предоставить синхронную версию асинхронного метода GetListInboundPlansAsync. Обычно считается антишаблоном из-за риска взаимоблокировок. См. также stackoverflow.com/questions/59018541/… и stackoverflow.com/questions/40324300/…

Klaus Gütter 31.05.2024 14:14
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, давайте сделаем небольшой обзор, поскольку здесь собрано много всего.


public int MethodName(int a) => a+5;

Это то же самое, что


public int MethodName(int a)
{
    return a + 5;
}

По сути, Method() => x; — это просто сокращение для возврата x. Чаще всего это используется, если значение повтора/его генерация представляет собой однострочник.

Итак, давайте воспользуемся этими знаниями для перевода вашего

public List<InboundPlanSummary> GetListInboundPlans(ParameterGetListInboundPlans parameterGetListInboundPlans) =>
    Task.Run(() => GetListInboundPlansAsync(parameterGetListInboundPlans)).ConfigureAwait(false).GetAwaiter().GetResult();

в


public List<InboundPlanSummary> GetListInboundPlans(ParameterGetListInboundPlans parameterGetListInboundPlans)
{
    return Task.Run(() => GetListInboundPlansAsync(parameterGetListInboundPlans)).ConfigureAwait(false).GetAwaiter().GetResult();
}

Теперь давайте посмотрим на

Task.Run(() => GetListInboundPlansAsync(parameterGetListInboundPlans)).ConfigureAwait(false).GetAwaiter().GetResult()

Чтобы упростить задачу, я разделю их для вас.

var a = Task.Run(() => GetListInboundPlansAsync(parameterGetListInboundPlans));
var b = a.ConfigureAwait(false);
var c = b.GetAwaiter();
var x = c.GetResult();

Task.Run(() => GetListInboundPlansAsync(parameterGetListInboundPlans)) Создает и запускает задачу. Эта задача выполняется GetListInboundPlansAsync(parameterGetListInboundPlans). Поскольку это то же имя метода, только с добавлением async, мы можем предположить/заключить, что GetListInboundPlansAsync возвращает List<InboundPlanSummary>, но асинхронным способом. Это означает, что то, что он возвращает, на самом деле не является полностью заполненным списком, а является задачей, которая все еще выполняет/заполняет этот список.

итак, наш a имеет тип Task<List<InboundPlanSummary>>

Чтобы побыстрее и для простоты, когда вы видите Task.Run(() => Meth()), игнорируйте часть () => и сосредоточьтесь на том, что будет дальше. Если вы хотите выполнить несколько задач за один запуск задачи, вы можете сделать это Task.Run(() => { //write like this is just a method})

ConfigureAwait(false) очень простыми словами определяет, что Задача/ожидание будет выполняться в другом потоке, а не в потоке, который его вызвал.

итак, наш b — это ConfiguredTaskAwaitable<List<InboundPlanSummary>>

GetAwaiter()ну вот и ожидающий Задания (это не так уж и важно)

и GetResult() получает результат задачи после ее завершения и завершает задачу/ожидание

Итак, скажем, у нас было var result = Task.Run(() => GetListInboundPlansAsync(parameterGetListInboundPlans)).ConfigureAwait(false).GetAwaiter().GetResult();

С учетом знаний, которые мы только что получили, мы можем сказать, что он делает следующее: Задаче приказывают поставить ее в очередь GetListInboundPlansAsync и запустить ее асинхронно в другом потоке в Threadpool ConfigureAwait(false). Затем захватите ожидаемый GetAwaiter и извлеките результат GetResult, чтобы наш result имел тип List<InboundPlanSummary>

И этот результат затем возвращается.

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

«определяет, что Задача/ожидание будет выполняться в другом потоке» — это неправильно. Он определяет, что после ожидания задачи код может возобновиться в другом контексте синхронизации.

Klaus Gütter 01.06.2024 08:56

@KlausGütter, тогда я прошу прощения. Насколько я понял, когда вы запускаете его с true, он имеет возможность блокировать потоки, как, например, потоки пользовательского интерфейса. Я с радостью заменю эту ошибку. Есть ли способ, которым вы рекомендуете написать это, чтобы новички могли его понять?

SMSTJ 03.06.2024 08:00

Упомянутая вами блокировка является результатом использования GetAwaiter().GetResult() ожидания завершения задачи, пока задача ожидает продолжения в том же потоке. См., например. blog.stephencleary.com/2012/07/dont-block-on-async-code.html

Klaus Gütter 03.06.2024 10:48

Другие вопросы по теме

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

Когда я нажимаю кнопку удаления, я получаю сообщение об ошибке и не нажимаю контроллер удаления в ASP.NET Core с Entity Framework Core
Не удалось найти свойство с именем «keyName» типа «MyClass» в ASP.NET Core OData 8.2.5
Сделайте снимок экрана, используя Directx11 под С#
Почему позже в скрипте массив объектов становится нулевым, даже после подтверждения того, что после инициализации он не равен нулю?
C# XUnit (.Net 8): параметр IFormFile в конечной точке, подлежащей тестированию, всегда принимается как нулевой
Как я могу запускать метод через определенные промежутки времени? System.Timers.Timer, кажется, теряет синхронизацию
Почему игровой объект игрока продолжает двигаться в воздухе, несмотря на то, что клавиши движения не нажимаются? (закрыто)
Выполняется ли Dispose of my Activity синхронно с кодом моего приложения?
Привязка WPF MVVM DataGrid к IEnumerable вызывает ошибки привязки к Int32
Как избежать бесконечного цикла перенаправления при объединении двух разных схем аутентификации (openIdConnect и ASP.NET Identity)?