Присвойте объекту какое-либо значение внутри Задачи объекта, поддерживая асинхронность

Я не очень разбираюсь в TPL.

Рассмотрим следующий сценарий:

У меня есть следующие занятия:

public class Contact
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public Company Company { get; set; }
}

public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Теперь у меня есть следующий фрагмент кода

Task<Contact> contactDetails = r.FirstOrDefaultAsync<Contact>();
Task<Company> companyDetails = r.FirstOrDefaultAsync<Company>();

Теперь я хочу заполнить свойство Company результатом companyDetails. что-то в этом роде (пожалуйста, проверьте ниже)

contactDetails.Company = companyDetails 

Я хочу сделать это без вызова функции ожидания для поддержки асинхронности.

Кто-нибудь, пожалуйста, помогите мне в этом?

companyDetails относится к типу Task<Company>, поэтому вы не можете просто назначить его переменной типа Company. Это больше похоже на обещание, что вы получите результат, как только оно будет выполнено. Вы можете вызвать Task<T>.Result для получения результата, однако имейте в виду, что вызывающий поток будет блокироваться до тех пор, пока задача не будет завершена, чего вы хотите избежать при использовании TPL ...
Johnny 14.10.2018 16:09

Да, мы можем сделать так, чтобы получить результат и присвоить его. Но это не то, что я ищу. Я хочу сделать это без блочного потока, пока не использую await.

Saadi 14.10.2018 16:13

@Saadi Не могли бы вы пояснить, почему вы не хотите использовать await?

pere57 15.10.2018 10:08

@ pere57, уже выделено в моем вышеупомянутом комментарии, что await block thread,

Saadi 16.10.2018 08:56

Downvoters - скажите, пожалуйста, что не так в этом вопросе?

Saadi 16.10.2018 08:57

Task <T> не является фактическим объектом. Как сказано выше, это обещание получить объект. Поэтому, когда у вас есть Task <T>, вы не можете назначать свойства объекту T. Task <T> может не возвращать объект T. Это может вызвать исключение.

Dylan 18.10.2018 04:24

Так что вам нужно дождаться Задачи и получить результат, прежде чем работать с объектом. Хотя вы можете поместить это в другую задачу, и тогда она будет выполняться только при ожидании задачи, что я показал.

Dylan 18.10.2018 04:31

@Saadi await не блокирует поток. Это асинхронное ожидание, а не ожидание с блокировкой. await - именно то, что вам нужно.

pere57 19.10.2018 03:29
Стоит ли изучать 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
8
352
1

Ответы 1

Скажем, вы создали асинхронный метод, как показано ниже:

public async Task<Contact> GetContact()
{
    R r = new R();

    Contact contactDetails = await r.FirstOrDefaultAsync<Contact>();
    Company companyDetails = await r.FirstOrDefaultAsync<Company>();

    contactDetails.Company = companyDetails;

    Console.WriteLine("3");
    return contactDetails;
}

Это не будет выполнено, пока вы не дождетесь этого GetContact. Так, например, если мы вызовем его, используя приведенный ниже код:

Console.WriteLine("1");
Task<Contact> getContactTask = GetContact();
Console.WriteLine("2");
Contact contact = await getContactTask; // the code is now executed
Console.WriteLine("4");

Консоль покажет:

1
2
3
4

Согласно вашему комментарию, я думаю, что это то, что вы хотите. Get contact and get company не будет выполняться, пока вы не вызовете await в методе GetContact.

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

public async Task<Contact> GetCompanyParallel()
{
    R r = new R();

    Task<Contact> contactDetailsTask = r.FirstOrDefaultAsync<Contact>();
    Task<Company> companyDetailsTask = r.FirstOrDefaultAsync<Company>();

    await Task.WhenAll(contactDetailsTask, companyDetailsTask);

    Contact contactDetails = await contactDetailsTask;
    contactDetails.Company = await companyDetailsTask;

    return contactDetails;
}

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