Task.Run - кол-во одновременных по умолчанию
От: Shmj Ниоткуда  
Дата: 05.03.20 23:36
Оценка:
Чего й то не понял:

    class Program
    {
        static async Task Main(string[] args)
        {
            for (int i = 0; i < 100; i++)
            {
                var copy = i;

                _ = Task.Run(() =>
                {
                    Console.WriteLine("Start " + copy);
                    Thread.Sleep(5000);
                    Console.WriteLine("End " + copy);
                });
            }

            Console.ReadLine();
            Console.WriteLine("Hello World!");
        }
    }


Одновременно запускается не так много задач — как я понял, по числу ядер процессора или типа того (на моем старичке — только 4 штуки). Где это установлено? В TaskScheduler.Current.MaximumConcurrencyLevel — офердофигища.
Отредактировано 05.03.2020 23:38 Shmj . Предыдущая версия .
Re: Task.Run - кол-во одновременных по умолчанию
От: fmiracle  
Дата: 06.03.20 05:45
Оценка: 3 (1)
Здравствуйте, Shmj, Вы писали:

S>Одновременно запускается не так много задач — как я понял, по числу ядер процессора или типа того (на моем старичке — только 4 штуки). Где это установлено? В TaskScheduler.Current.MaximumConcurrencyLevel — офердофигища.


Таски тут ни при чем.

Task.Run использует для выполнения задач ThreadPool. ThreadPool, в свою очередь — это класс, который позволяет переиспользовать потоки, потому что создавать новый поток — довольно дорого.
Приложение у тебя свеженькое, в пул потоков не заполнен. Потому ThreadPool запускает обработки на нескольких потоках, остальные в очередь. И только позже, видя, что имеющихся потоков никак не хватает начинает (довольно неохотно) создавать новые.

Можешь доработать код, добавив в начало раскачку пула потоков:
for( int i = 0; i < 50; i++ )
            {
                var copy = i;
                ThreadPool.QueueUserWorkItem( ( state ) => {
                    Console.WriteLine( "init pool" );
                    Thread.Sleep( 3000 );
                } );
            }
            Thread.Sleep( 20000 );


а после — прошлый код и увидишь, что теперь в нем стало сразу стартовать куда больше задач.
Re: Есть целых два древних TaskScheduler-а
От: VladCore  
Дата: 06.03.20 07:07
Оценка:
Здравствуйте, Shmj, Вы писали:

Есть целых два древних TaskScheduler-а
Оба очень древние под древний дотнет:
int maxThreads = 2;
LimitedConcurrencyLevelTaskScheduler lcs = new LimitedConcurrencyLevelTaskScheduler(maxThreads);
QueuedTaskScheduler qs = new QueuedTaskScheduler(maxThreads);
TaskFactory factory = new TaskFactory(qs|lcs);

...
await factory.StartNew(() => ...);


QueuedTaskScheduler — этот с кучей плюшек но работает только на Windows, хотя и в .NET Core тоже. Но он и может юзать свой массив потоков и делегировать исполнение тасков заданному TaskScheduler-у.

LimitedConcurrencyLevelTaskScheduler — этот везде работает, но юзает всегда ThreadPool.

Я юзал оба. Хотя и сейчас юзаю.

На github очень много форков. Вот один из самых популярных: https://www.nuget.org/packages/ParallelExtensionsExtras/

S>Чего й то не понял:


S>
S>    class Program
S>    {
S>        static async Task Main(string[] args)
S>        {
S>            for (int i = 0; i < 100; i++)
S>            {
S>                var copy = i;

S>                _ = Task.Run(() =>
S>                {
S>                    Console.WriteLine("Start " + copy);
S>                    Thread.Sleep(5000);
S>                    Console.WriteLine("End " + copy);
S>                });
S>            }

S>            Console.ReadLine();
S>            Console.WriteLine("Hello World!");
S>        }
S>    }
S>


S>Одновременно запускается не так много задач — как я понял, по числу ядер процессора или типа того (на моем старичке — только 4 штуки). Где это установлено? В TaskScheduler.Current.MaximumConcurrencyLevel — офердофигища.
Отредактировано 06.03.2020 7:39 VladCore . Предыдущая версия . Еще …
Отредактировано 06.03.2020 7:16 VladCore . Предыдущая версия .
Re: Task.Run - кол-во одновременных по умолчанию
От: Danchik Украина  
Дата: 06.03.20 07:17
Оценка: +4
Здравствуйте, Shmj, Вы писали:

S>Чего й то не понял:


Ты очень не понял, если в код таски впаял Thread.Sleep(5000)
Таски как раз и придуманы чтобы переиспользовать потоки, а ты их блоканул.
Для этого дела есть
await Task.Delay(5000)
Re[2]: Task.Run - кол-во одновременных по умолчанию
От: Shmj Ниоткуда  
Дата: 06.03.20 07:46
Оценка: +1
Здравствуйте, fmiracle, Вы писали:

F>Task.Run использует для выполнения задач ThreadPool. ThreadPool, в свою очередь — это класс, который позволяет переиспользовать потоки, потому что создавать новый поток — довольно дорого.


Да, задать можно в ThreadPool.SetMinThreads(100, 1);

Может и дорого, но данный код выполняется быстрее во много крат, если одновременно стартануть все 100 потоков (т.к. большую часть времени просто ждет).
Re[3]: Task.Run - кол-во одновременных по умолчанию
От: fmiracle  
Дата: 06.03.20 08:42
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Может и дорого, но данный код выполняется быстрее во много крат, если одновременно стартануть все 100 потоков (т.к. большую часть времени просто ждет).


Оптимизация тредпула не предназначена для таких задач. Для подобных задач (долгие ожидания) хороши как раз await-able таски.
Re: Task.Run - кол-во одновременных по умолчанию
От: alexzzzz  
Дата: 06.03.20 14:44
Оценка: 6 (1) +1
Здравствуйте, Shmj, Вы писали:

S>Одновременно запускается не так много задач — как я понял, по числу ядер процессора или типа того (на моем старичке — только 4 штуки). Где это установлено? В TaskScheduler.Current.MaximumConcurrencyLevel — офердофигища.


Поскольку таски долгоживущие, запускай их соответственно:
var task = Task.Factory.StartNew(() =>
    {
        Console.WriteLine("Start " + copy);
        Thread.Sleep(5000);
        Console.WriteLine("End " + copy);
    },
    TaskCreationOptions.LongRunning
);
Re[3]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 07.03.20 07:04
Оценка: -1
Здравствуйте, Shmj, Вы писали:

S>Может и дорого, но данный код выполняется быстрее во много крат


Ускорение Thread.Sleep — великое твое достижение, да.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: Task.Run - кол-во одновременных по умолчанию
От: Shmj Ниоткуда  
Дата: 07.03.20 12:25
Оценка: :)
Здравствуйте, Ночной Смотрящий, Вы писали:

S>>Может и дорого, но данный код выполняется быстрее во много крат

НС>Ускорение Thread.Sleep — великое твое достижение, да.

Вопрос не этом.
Re[5]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 07.03.20 17:51
Оценка:
Здравствуйте, Shmj, Вы писали:

НС>>Ускорение Thread.Sleep — великое твое достижение, да.

S>Вопрос не этом.

Вопрос именно в этом. Ты сперва блокируешь потоки, а потом прям открытие делаешь, что если блокированные потоки размножить, то работать начинает быстрее.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[6]: Task.Run - кол-во одновременных по умолчанию
От: Shmj Ниоткуда  
Дата: 07.03.20 20:57
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Вопрос именно в этом. Ты сперва блокируешь потоки, а потом прям открытие делаешь, что если блокированные потоки размножить, то работать начинает быстрее.


Вопрос был: "Где это установлено?"
Re: Task.Run - кол-во одновременных по умолчанию
От: GlebZ Россия  
Дата: 07.03.20 21:36
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Одновременно запускается не так много задач — как я понял, по числу ядер процессора или типа того (на моем старичке — только 4 штуки). Где это установлено? В TaskScheduler.Current.MaximumConcurrencyLevel — офердофигища.

Значение зависит от состояния виртуальной памяти и количества ядер. Основная проблема открытия потока — это то что он минимум занимает виртуальную память под стек(насколько я помню — 2 мега). Для того чтобы программа не была подвержена DDos атакам, и всяким глупостям программистов создающим кратковременные пиковые нагрузки, сделано что новый поток открывается в ThreadPool только с некоторой задержкой, в надежде что освободится уже выполненный поток. SetMinThreads поможет, если задача реально должна потреблять столько потоков (задач).
Re[7]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 07.03.20 21:39
Оценка:
Здравствуйте, Shmj, Вы писали:

НС>>Вопрос именно в этом. Ты сперва блокируешь потоки, а потом прям открытие делаешь, что если блокированные потоки размножить, то работать начинает быстрее.

S>Вопрос был: "Где это установлено?"

Тебе сразу же сказали про ThreadPool. Но я то не на то сообщение отвечал, а на вот это прекрасное заявление:

Может и дорого, но данный код выполняется быстрее во много крат, если одновременно стартануть все 100 потоков (т.к. большую часть времени просто ждет).


Т.е. ты заведомо кривой код вылечил кривым костылем, о чем я тебе и намекнул.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[8]: Task.Run - кол-во одновременных по умолчанию
От: Shmj Ниоткуда  
Дата: 07.03.20 23:03
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>

НС>Может и дорого, но данный код выполняется быстрее во много крат, если одновременно стартануть все 100 потоков (т.к. большую часть времени просто ждет).


НС>Т.е. ты заведомо кривой код вылечил кривым костылем, о чем я тебе и намекнул.


Так, давай разберемся что ты хочешь донести. Что значит "кривой код"?

Да, потоки блокируем с помощью Sleep. И что? Ты вообще принципиально против блокировок потоков? Напиши свой вариант без блокировки потоков в теме: http://rsdn.org/forum/dotnet/7674190.flat
Автор: Shmj
Дата: 06.03.20
— обкашляем.
Re[9]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 07.03.20 23:08
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Так, давай разберемся что ты хочешь донести. Что значит "кривой код"?


Ты точно программист?

S>Да, потоки блокируем с помощью Sleep. И что?


И то что это в подавляющем большинстве ситуаций плохо.

S> Ты вообще принципиально против блокировок потоков?


В сценариях когда тебе требуются сотни потоков — да, против.

S> Напиши свой вариант без блокировки потоков в теме: http://rsdn.org/forum/dotnet/7674190.flat
Автор: Shmj
Дата: 06.03.20
— обкашляем.


Как я тебе напишу без блокировки, если у тебя там тоже одни слипы? Запрос к серверу обычно можно делать через IOCP.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[10]: Task.Run - кол-во одновременных по умолчанию
От: Shmj Ниоткуда  
Дата: 07.03.20 23:49
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

S>>Так, давай разберемся что ты хочешь донести. Что значит "кривой код"?

НС>Ты точно программист?

Моя личность не имеет отношения к делу.

НС>И то что это в подавляющем большинстве ситуаций плохо.


Кстати, а за счет чего достигается задержка с помощью Task.Delay? Чего-то не смотрел внутренности.

>Как я тебе напишу без блокировки, если у тебя там тоже одни слипы? Запрос к серверу обычно можно делать через IOCP.


Ну, там где запрос к серверу — можно и оставить блокировку, она не на долго. А вот где ожидание — Task.Delay.
Re[11]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 08.03.20 00:03
Оценка:
Здравствуйте, Shmj, Вы писали:

S>>>Так, давай разберемся что ты хочешь донести. Что значит "кривой код"?

НС>>Ты точно программист?
S>Моя личность не имеет отношения к делу.

Зато имеют задаваемые тобой вопросы. Ты меня еще спроси что такое код.

НС>>И то что это в подавляющем большинстве ситуаций плохо.

S>Кстати, а за счет чего достигается задержка с помощью Task.Delay? Чего-то не смотрел внутренности.

Ну так посмотри. Таймер там.

>>Как я тебе напишу без блокировки, если у тебя там тоже одни слипы? Запрос к серверу обычно можно делать через IOCP.

S>Ну, там где запрос к серверу — можно и оставить блокировку, она не на долго. А вот где ожидание — Task.Delay.

Ну так вперед. Заменить свои слипы и посмотреть что вышло — быстрее чем это сообщение писать.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[12]: Task.Run - кол-во одновременных по умолчанию
От: Shmj Ниоткуда  
Дата: 08.03.20 00:39
Оценка: -1
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>И то что это в подавляющем большинстве ситуаций плохо.

S>>Кстати, а за счет чего достигается задержка с помощью Task.Delay? Чего-то не смотрел внутренности.

НС>Ну так посмотри. Таймер там.


А таймер насколько менее ресурсоемок, нежели создание потока?
Re[13]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 08.03.20 00:50
Оценка:
Здравствуйте, Shmj, Вы писали:

НС>>Ну так посмотри. Таймер там.

S>А таймер насколько менее ресурсоемок, нежели создание потока?

Блин, да напиши уже код.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[14]: Task.Run - кол-во одновременных по умолчанию
От: Shmj Ниоткуда  
Дата: 08.03.20 09:47
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Блин, да напиши уже код.


Проверил. 1000 блокированных потоков отжирают около +25 МБ ОЗУ. На самом деле не критично — копейки. Но ради чистоты идеи — да, лучше заюзать таймеры.
Re[15]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 08.03.20 12:25
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Проверил. 1000 блокированных потоков отжирают около +25 МБ ОЗУ.


Дело не в ОЗУ, дело в производительности и масштабируемости.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[2]: Task.Run - кол-во одновременных по умолчанию
От: Sharov Россия  
Дата: 10.03.20 10:14
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Значение зависит от состояния виртуальной памяти и количества ядер.


А можно про это подробнее?

GZ>Основная проблема открытия потока — это то что он минимум занимает виртуальную память под стек(насколько я помню — 2 мега).


1мб по умолчанию.
Кодом людям нужно помогать!
Re[3]: Task.Run - кол-во одновременных по умолчанию
От: GlebZ Россия  
Дата: 10.03.20 14:37
Оценка:
Здравствуйте, Sharov, Вы писали:

GZ>>Значение зависит от состояния виртуальной памяти и количества ядер.

S>А можно про это подробнее?
Подробнее — сам не вкурсах. Раньше было детерменированное количество потоков по умолчанию, которое зависило от количество процессоров. Теперь они зацепили состояние виртуальной памяти, что и как не в курсах. В документации было только это.

GZ>>Основная проблема открытия потока — это то что он минимум занимает виртуальную память под стек(насколько я помню — 2 мега).

S>1мб по умолчанию.
Ага. Посмотрел — именно так. Не знаю откуда взял 2 метра.
Re[4]: Task.Run - кол-во одновременных по умолчанию
От: Sharov Россия  
Дата: 10.03.20 14:44
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Подробнее — сам не вкурсах. Раньше было детерменированное количество потоков по умолчанию, которое зависило от количество процессоров. Теперь они зацепили состояние виртуальной памяти, что и как не в курсах. В документации было только это.


А можно ссыль на доку?
Кодом людям нужно помогать!
Re[5]: Task.Run - кол-во одновременных по умолчанию
От: GlebZ Россия  
Дата: 10.03.20 19:08
Оценка: 5 (1)
Здравствуйте, Sharov, Вы писали:

GZ>>Подробнее — сам не вкурсах. Раньше было детерменированное количество потоков по умолчанию, которое зависило от количество процессоров. Теперь они зацепили состояние виртуальной памяти, что и как не в курсах. В документации было только это.


S>А можно ссыль на доку?

Нашел.

Maximum number of thread pool threads
The number of operations that can be queued to the thread pool is limited only by available memory. However, the thread pool limits the number of threads that can be active in the process simultaneously. If all thread pool threads are busy, additional work items are queued until threads to execute them become available. Beginning with the .NET Framework 4, the default size of the thread pool for a process depends on several factors, such as the size of the virtual address space. A process can call the ThreadPool.GetMaxThreads method to determine the number of threads.

You can control the maximum number of threads by using the ThreadPool.GetMaxThreads and ThreadPool.SetMaxThreads methods.

Note

Code that hosts the common language runtime can set the size using the ICorThreadpool::CorSetMaxThreads method.

Thread pool minimums
The thread pool provides new worker threads or I/O completion threads on demand until it reaches a specified minimum for each category. You can use the ThreadPool.GetMinThreads method to obtain these minimum values.

Note

When demand is low, the actual number of thread pool threads can fall below the minimum values.

When a minimum is reached, the thread pool can create additional threads or wait until some tasks complete. Beginning with the .NET Framework 4, the thread pool creates and destroys worker threads in order to optimize throughput, which is defined as the number of tasks that complete per unit of time. Too few threads might not make optimal use of available resources, whereas too many threads could increase resource contention.

Caution

You can use the ThreadPool.SetMinThreads method to increase the minimum number of idle threads. However, unnecessarily increasing these values can cause performance problems. If too many tasks start at the same time, all of them might appear to be slow. In most cases the thread pool will perform better with its own algorithm for allocating threads.

https://docs.microsoft.com/ru-ru/dotnet/api/system.threading.threadpool.getavailablethreads?view=netframework-4.8

Когда я читал(возможно не здесь, за давностью лет не помню), я сделал вывод, что ни за что нельзя быть уверенным. Я не знаю, насколько это хорошо или плохо, что они по своим непонятным правилам начали выделять потоки, но копать глубже мне по решаемым задачам мне не надо было. В тяжелых многопоточных задачах необходимо контролировать нагрузку самостоятельно.
Re[6]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 10.03.20 20:48
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>В тяжелых многопоточных задачах необходимо контролировать нагрузку самостоятельно.


Или просто не блокировать надолго workitem threads.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[7]: Task.Run - кол-во одновременных по умолчанию
От: GlebZ Россия  
Дата: 10.03.20 21:11
Оценка: 86 (3)
Здравствуйте, Ночной Смотрящий, Вы писали:

GZ>>В тяжелых многопоточных задачах необходимо контролировать нагрузку самостоятельно.

НС>Или просто не блокировать надолго workitem threads.
Это индивидуально. Всегда решается компромис между производительностью и эффективностью системы и сложностью реализации, а следовательно багоемкости решения. Например, для меня очень часто важнее чистота стека, поэтому у меня мало серверного кода с await функциями. Если бутылочным горлышком является, например, БД или чужой сервис, то я бессовестно блокирую ими, потому что у них есть свои системы управлением нагрузкой, проц в этот момент не юзается, а память не жалко. Если бутылка — в процессоре, то кастомный шедулер с очередью. Я помню только одно мое приложение которое отдавало потоки в пул, и то — это была реализация IHttpAsyncHandler.
Re[6]: Task.Run - кол-во одновременных по умолчанию
От: Mr.Delphist  
Дата: 11.03.20 10:22
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Здравствуйте, Sharov, Вы писали:


GZ>>>Подробнее — сам не вкурсах. Раньше было детерменированное количество потоков по умолчанию, которое зависило от количество процессоров. Теперь они зацепили состояние виртуальной памяти, что и как не в курсах. В документации было только это.


Сейчас в NetCore оно вообще зависит от платформы (Win/Linux), битности (32/64), процессора (ARM/x86) и кто знает чего ещё. Т.е. можно (и нужно) думать про это как implementation details.
Re[8]: Task.Run - кол-во одновременных по умолчанию
От: Sharov Россия  
Дата: 11.03.20 11:44
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Это индивидуально. Всегда решается компромис между производительностью и эффективностью системы и сложностью реализации, а следовательно багоемкости решения. Например, для меня очень часто важнее чистота стека, поэтому у меня мало серверного кода с await функциями.


Stacktrace при исключении или при отладке? Что там такого грязного?
Кодом людям нужно помогать!
Re[9]: Task.Run - кол-во одновременных по умолчанию
От: GlebZ Россия  
Дата: 11.03.20 14:31
Оценка:
Здравствуйте, Sharov, Вы писали:

GZ>>Это индивидуально. Всегда решается компромис между производительностью и эффективностью системы и сложностью реализации, а следовательно багоемкости решения. Например, для меня очень часто важнее чистота стека, поэтому у меня мало серверного кода с await функциями.


S>Stacktrace при исключении или при отладке? Что там такого грязного?

Специфика — что системы удаленные, и приходится очень щепетильно подходить к логам. Кроме восстановления самого порядка вызовов, нам очень важно иметь свой ManagedThreadId на каждый сценарий. Тогда проще восстановить как стек, так и порядок вызовов функций.
Re[10]: Task.Run - кол-во одновременных по умолчанию
От: Sharov Россия  
Дата: 11.03.20 15:03
Оценка:
Здравствуйте, GlebZ, Вы писали:

S>>Stacktrace при исключении или при отладке? Что там такого грязного?

GZ>Специфика — что системы удаленные, и приходится очень щепетильно подходить к логам. Кроме восстановления самого порядка вызовов, нам очень важно иметь свой ManagedThreadId на каждый сценарий. Тогда проще восстановить как стек, так и порядок вызовов функций.

async\await не ломает порядок вызов, а если есть привязка к ManagedThreadId ну тогда ладно.
Кодом людям нужно помогать!
Re[10]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 11.03.20 15:56
Оценка: +1
Здравствуйте, GlebZ, Вы писали:

S>>Stacktrace при исключении или при отладке? Что там такого грязного?

GZ>Специфика — что системы удаленные, и приходится очень щепетильно подходить к логам.

Ben.Demystifier не спасает?

GZ> Кроме восстановления самого порядка вызовов, нам очень важно иметь свой ManagedThreadId на каждый сценарий.


И в чем проблема? AsyncLocal вроде никто не отменял.

GZ> Тогда проще восстановить как стек, так и порядок вызовов функций.


И ради этого делать блокирующие вызовы?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[11]: Task.Run - кол-во одновременных по умолчанию
От: GlebZ Россия  
Дата: 11.03.20 21:05
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

GZ>>Специфика — что системы удаленные, и приходится очень щепетильно подходить к логам.

НС>Ben.Demystifier не спасает?
У меня свой инструментарий.

GZ>> Кроме восстановления самого порядка вызовов, нам очень важно иметь свой ManagedThreadId на каждый сценарий.

НС>И в чем проблема? AsyncLocal вроде никто не отменял.
Это достаточно новая фича.

GZ>> Тогда проще восстановить как стек, так и порядок вызовов функций.

НС>И ради этого делать блокирующие вызовы?
Для начала необходимо сказать зачем нужны неблокирующие вызовы. Вот кроме синтаксического сахара для визуального потока — придумать не могу. Когда он только появился, мы один из продуктов делали на Windows RT(еще на этапе Metro). Там ничего кроме async/await не было. На всех уровнях, вплоть до БД. И тут надо интегрировать библиотеку, которая генерит визуалку, и которая использует внутрях GDI+, а следовательно все вызовы должны быть в одном потоке. Радостей было, танцев с бубном, позвякивания колокольчиками учитывая что примитивов синхронизации практически нет(семафор и всё). Много удовольствия. Поэтому — как синтаксический сахар для визуалки, в том числе уровня UWP — на здоровье. Если серверный код — то спасибо, не стоит повышать сложность, ее и так хватает.
Re[12]: Task.Run - кол-во одновременных по умолчанию
От: Ночной Смотрящий Россия  
Дата: 12.03.20 08:46
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Для начала необходимо сказать зачем нужны неблокирующие вызовы. Вот кроме синтаксического сахара для визуального потока — придумать не могу.


Однако.

GZ> Когда он только появился, мы один из продуктов делали на Windows RT(еще на этапе Metro).


А, десктоп. Ну тогда понятно.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.