Как асинхронные методы работают в C#?

Я думаю, что это во многом зависит от числа, которое Вы планируете на включении. Если и 'b' не будет 'хорошее' число тогда, то Вы, вероятно, получите значение, которое не завершается, который невозможно сохранить и если C# BigDecimal ведет себя вообще как Java BigDecimal, это, вероятно, выдает исключение в таком случае.

7
задан Umar Abbas 15 April 2014 в 10:45
поделиться

4 ответа

Код - это железная дорога, а нить - это поезд. Когда поезд движется по железной дороге, он выполняет код.

BeginMyMethod выполняется основным потоком. Если вы заглянете внутрь BeginMyMethod , он просто добавит делегата MyMethod в очередь ThreadPool . Фактический MyMethod выполняется одним из составов группы поездов. Подпрограмма завершения, которая вызывается при выполнении MyMethod , выполняется тем же потоком, который выполнил MyMethod , а не вашим основным потоком, выполняющим остальной код. Пока поток пула потоков занят выполнением MyMethod , основной поток может либо использовать какую-либо другую часть железнодорожной системы (выполнять другой код), либо просто спать, ожидание, пока не загорится определенный семафор.

Следовательно, не существует такой вещи, как IAsyncResult , «знающий», когда вызывать подпрограмму завершения, вместо этого подпрограмма завершения - это просто делегат, вызываемый потоком пула потоков сразу после его завершения, выполняя MyMethod .

Надеюсь, вы не возражаете против несколько детской аналогии с поездом, я знаю, что она мне не раз помогала при объяснении многопоточности людям.

3
ответ дан 7 December 2019 в 12:22
поделиться

Асинхронные методы работают с использованием .NET ThreadPool . Они перенесут работу в поток ThreadPool (потенциально создавая его при необходимости, но обычно просто повторно используя его), чтобы работать в фоновом режиме.

В вашем случае вы можете делать то, что вы однако следует понимать, что пул потоков имеет ограниченное количество потоков, с которыми он будет работать. Вы собираетесь создать свою работу в фоновых потоках, и первый будет запущен немедленно, но через некоторое время они встанут в очередь и не будут работать, пока «задачи» не будут выполнены полностью. В результате будет казаться, что нити будут длиться все дольше и дольше.

Однако ваши критерии секундомера несколько ошибочны. Вы должны измерить общее время, необходимое для выполнения N задач, а не N раз для выполнения одной задачи.

1
ответ дан 7 December 2019 в 12:22
поделиться

Суть в том, что вызов Begin ставит в очередь запрос на выполнение вашего метода. Метод фактически выполняется в ThreadPool, который представляет собой набор рабочих потоков, предоставляемых средой выполнения.

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

Для отслеживания продолжительности времени требуется для фактического выполнения асинхронного метода, вы должны запускать и останавливать таймер в начале и в конце вашего метода.

Вот документы для класса ThreadPool ,

1
ответ дан 7 December 2019 в 12:22
поделиться

Возможно, большая часть времени выполнения происходит до BeginMyMethod () . В этом случае ваше измерение будет слишком низким. Фактически, в зависимости от API, BeginMyMethod () может вызвать обратный вызов перед выходом из самого стека. Перемещение вызова StopWatch.Start () должно тогда помочь.

0
ответ дан 7 December 2019 в 12:22
поделиться
Другие вопросы по тегам:

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