Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
 Аватар для BaredJJ
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447

Await вложенный в await

13.04.2018, 11:02. Показов 2360. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите, вот есть код
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Foo1
{
       //Body class
}
 
public class Foo2:Foo1
{
       //Body class
}
 
public class My
{
    public List<Foo2> foo2List = new List<Foo2>();
    private async Task<Foo1> GetFoo1() { await Task.Run(() => return new Foo2() as Foo1);}
    private async Task<Foo2> GetFoo2(Foo1 instance) => await instance as Foo2;
    public async Task Complited(){foo2List.Add(await GetFoo2(await GetFoo1)); } 
}
 
public class Programm
{
    public static void Main()
   {
        My myInstance = new My();
        Task.Run(async () => {await myInstance.Complited();
                                         await myInstance.Complited();
                                         await myInstance.Complited();
                                         await myInstance.Complited();});
         foreach(var my in  myInstance.foo2List)
             Console.WriteLine(my.ToString());
 
          Console.ReadKey();
   }
 
}
Меня очень интересует, что происходит в методе Complited класса My и действительно ли в коллекцию добавятся новые экземпляры класса. Я знаю что await от метода async Task<T> Comp() <=> Task<T> t = Comp(); T = await t;. Т.е. все должно сработать, но у меня почему то получается пустой список. Вопрос в кривости моих рук или тут, что то еще происходит и в цикле foreach в примере выше я действительно сумею просмотреть все добавившиеся элементы списка.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.04.2018, 11:02
Ответы с готовыми решениями:

Async/await
В интернете копался ничего информативного не нашел, все в каких- то не понятных для новичка терминах, объясните пожалуйста смысл...

Не работает await
Код dll using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; ...

async/await (._. )
Опять я с глупым вопросом. Не могу понять, почему метод, который выгружает данные не асинхронный? Вообще форма зависает на неопределенное...

9
79 / 102 / 44
Регистрация: 12.05.2015
Сообщений: 476
13.04.2018, 11:26
Цитата Сообщение от BaredJJ Посмотреть сообщение
почему то получается пустой список
Стало быть, вы пытаетесь вывести список раньше, чем отработает задача, надо подождать пока она выполнится, а потом списки выводить.
C#
1
2
3
4
5
6
Task.Run(async () => {
    await myInstance.Complited();
    await myInstance.Complited();
    await myInstance.Complited();
    await myInstance.Complited();
}).Wait();
0
 Аватар для BaredJJ
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
13.04.2018, 11:29  [ТС]
Нет это хорошо. Но что насчет вложенных await, там нет никаких подводных камней? Действительно ли порядок и передаваемые данные не теряются? Что происходит с инкапсулированными классами?
0
 Аватар для m0nax
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
13.04.2018, 11:52
C#
1
2
3
4
 await myInstance.Complited();
    await myInstance.Complited();
    await myInstance.Complited();
    await myInstance.Complited();
в текущем виде это совершенно бессмысленно и даже немного вредно
есть специальные методы вроде Task.WaitAll для ожидания сразу всех задач
1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.04.2018, 12:23
Цитата Сообщение от BaredJJ Посмотреть сообщение
C#
1
GetFoo2(Foo1 instance) => await instance as Foo2;
Эта конструкция подразумевает что в классах Foo1/Foo2 реализован метод GetAwaiter, но реализации нигде не видно.
Возможно, ошибка там.
1
 Аватар для BaredJJ
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
13.04.2018, 12:50  [ТС]
Цитата Сообщение от kolorotur Посмотреть сообщение
Эта конструкция подразумевает что в классах Foo1/Foo2 реализован метод GetAwaiter, но реализации нигде не видно.
Возможно, ошибка там.
Вот в этом возможно есть правда. То есть при DownCast я должен, что то дополнительно реализовывать. Этот пример я просто придумал только что и даже его не проверял. Просто при реализации хотел попробовать дождаться всех задач способом описанным у А.Дэвиса в книге Асинхронное программирование.
вот его код:
C#
1
2
3
4
5
6
7
8
List<Task<Image>> tasks = new List<Task<Image>>();
foreach(string domain in s_Domain)
   tasks.Add(GetFavicon(domain));
 
Task<Image[]> allTasks = Task.WhenAll(tasks);
Image[] images = await allTasks;
foreach(var Image eachImage in images)
  AddFavicon(eachImage);
ну я переделал его для себя:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
                List<Task<ContainerRecivedMessage>> tasks = new List<Task<ContainerRecivedMessage>>();
                for(int i = 0; i < lamp.Commands.Count; i++)
                {
                    byte[] message = BitConverter.GetBytes(lamp.Commands[i].Code);
                    byte temp = message[0];
                    message[0] = message[1];
                    message[1] = temp;
                    tasks.Add(
                        await client.SendAsync(new Rdm().ArtRdmMessage(
                        new SentRdm().RdmPacketMessage(
                        lamp, 
                        lamp.ParentNode.Port,
                        ParametrCommand.RDM_GET_COMMAND,
                        ParametrID.RDM_PARAMETER_DESCRIPTION, message), version, 
                        lamp.ParentNode.Universe),
                        lamp.ParentNode.PerentDevice.Address)
                    );
                    Task<ContainerRecivedMessage[]> allTasks = Task.WhenAll(tasks);
                    ContainerRecivedMessage[] container = await allTasks;
                    for(int j = 0; j < container.Length; j++)
                        await NewMessageCheckNull(conteiner[i]);
 
                }
Так как список у меня был инициализирован изначально и элементы в нем тоже были инициализированы, то значения в нем были по умолчанию. Такими они оставались и после ожидания завершения всех задач. То есть на выходе я получал просто иниуиализированный по умолчанию массив. Но при использовании поля на уровне класса типа ContainerRecivedMessage с таким вот кодом все заполнялось:
C#
1
2
3
4
5
6
7
8
9
containerRecivedMessage = await client.SendAsync(new Rdm().ArtRdmMessage(
                        new SentRdm().RdmPacketMessage(
                        lamp, 
                        lamp.ParentNode.Port,
                        ParametrCommand.RDM_GET_COMMAND,
                        ParametrID.RDM_PARAMETER_DESCRIPTION, message), version, 
                        lamp.ParentNode.Universe),
                        lamp.ParentNode.PerentDevice.Address);
await NewMessageCheckNull(containerRecivedMessage);
При следующей записи значения тоже были по умолчанию:
C#
1
2
3
4
5
6
7
8
9
10
await NewMessageCheckNull(
                        await client.SendAsync(new Rdm().ArtRdmMessage(
                        new SentRdm().RdmPacketMessage(
                        lamp, 
                        lamp.ParentNode.Port,
                        ParametrCommand.RDM_GET_COMMAND,
                        ParametrID.RDM_PARAMETER_DESCRIPTION, message), version, 
                        lamp.ParentNode.Universe),
                        lamp.ParentNode.PerentDevice.Address)
                        );
Отсюда и вопрос)

Добавлено через 2 минуты
Цитата Сообщение от m0nax Посмотреть сообщение
C#
1
2
3
4
 await myInstance.Complited();
    await myInstance.Complited();
    await myInstance.Complited();
    await myInstance.Complited();
в текущем виде это совершенно бессмысленно и даже немного вредно
есть специальные методы вроде Task.WaitAll для ожидания сразу всех задач
А WaitAll чем отличается от WhenAll? Разве не WhenAll Нужно использовать и если какие то недостатки при использование на разных платформах, скажем wpf, asp?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.04.2018, 13:39
Цитата Сообщение от BaredJJ Посмотреть сообщение
при DownCast я должен, что то дополнительно реализовывать.
Нет.
Не путайте тип переменной и фактический объект, на который эта переменная ссылается.

Цитата Сообщение от BaredJJ Посмотреть сообщение
Отсюда и вопрос
Покажите реализацию классов Foo1 и Foo2 из первого поста.

Цитата Сообщение от BaredJJ Посмотреть сообщение
А WaitAll чем отличается от WhenAll?
Блокировкой ожидания.

Цитата Сообщение от BaredJJ Посмотреть сообщение
Разве не WhenAll Нужно использовать
Если используется асинхронное ожидание, то его.

Цитата Сообщение от BaredJJ Посмотреть сообщение
если какие то недостатки при использование на разных платформах, скажем wpf, asp?
Недостатки в основном не в платформах, а в возможности повесить приложение наглухо при комбинации асинхронных и блокирующих вызовов.
1
 Аватар для BaredJJ
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
13.04.2018, 13:51  [ТС]
Да нет никакой реализации в этих классах. Я просто макет набросал, чтобы наглядно, а не словесно объяснятся. Приблизительно в такой ситуации у меня получался пустой список, как из поста выше.
Ситуацию я описывал частично здесь TAP метод не выводит два последних значения в цикле
Вообще реализация большая и я уже сделал по другому. Мне просто очень интересно, что это какое особое поведение или мои кривые руки, что то делают не так?

Не путайте тип переменной и фактический объект, на который эта переменная ссылается.
Здесь объясните пожалуйста. Не понимаю. Вот у нас объект instance мы приводим его к другому типу, а потом приводим обратно. Разве это не down cast? Поправьте меня в чем тут ошибка или объясните. Спасибо
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
13.04.2018, 15:25
Цитата Сообщение от BaredJJ Посмотреть сообщение
Да нет никакой реализации в этих классах.
То есть пример из первого поста не компилируется, правильно?

Цитата Сообщение от BaredJJ Посмотреть сообщение
Я просто макет набросал, чтобы наглядно, а не словесно объяснятся. Приблизительно в такой ситуации у меня получался пустой список, как из поста выше.
А вы сделайте минимальный компилируищийся пример, который воспроизводит вашу проблему. Без вызова всяких сторонних библиотек.

Цитата Сообщение от BaredJJ Посмотреть сообщение
Вот у нас объект instance мы приводим его к другому типу, а потом приводим обратно. Разве это не down cast?
Есть два вида каста: конвертирование значение и приведение ссылки.
В первом случае создается новый экземпляр, не имеющий отношения к первому — как при касте double в int, например.
Во втором и в вашем случае просто меняется тип переменной, при этом никак не изменяется объект, на который эта переменная ссылается.
В вашем случае в методе GetFoo2 — да, down cast, но эта операция применяется к изменению типа переменной.
0
 Аватар для BaredJJ
19 / 18 / 7
Регистрация: 16.05.2017
Сообщений: 447
13.04.2018, 15:40  [ТС]
В вашем случае в методе GetFoo2 — да, down cast, но эта операция применяется к изменению типа переменной.
Соглашусь с вами, но как это влияет на работу await или это просто поправка меня?

То есть пример из первого поста не компилируется, правильно?
Не компилируется. Пришлось внести изменения.
C#
1
2
        private async Task<Foo2> GetFoo2(Foo1 instance) => await Task.Run(() => instance as Foo2);
//Ругался на недостающий метод в классе GetAwaiter();
ну и нужно было Wait() подправить как ответили в 4 сообщение в топике.

Добавлено через 33 секунды
А воссоздать, да я попробую.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.04.2018, 15:40
Помогаю со студенческими работами здесь

async/await
https://metanit.com/sharp/tutorial/13.7.php вот код Task&lt;T&gt;: // определение асинхронного метода static async...

Async await
Пытыюсь разобраться с async/await но что то без успешно пока. Не подскажете как переделать этот код на примере проще освоить public...

try...catch и await
Сделал простую ошибку public partial class App : Application { IStDorModel model; MainViewModel viewModel;...

Async await, использование
Знатоки, есть ли разница между написанием? Я где-то читал, что второй способ хуже, ибо создается IO поток и CPU, а в первом только IO ...

Проблемы с async и await
Добрый день. Помогите разобраться c api, для начала вот код Метод класса: async public Task&lt;bool&gt; Auth() ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru