Может бесконечное асинхронное переполнение стека

Я также нашел простое, более простое решение. То есть с помощью атрибута screen.width и проверки диапазона ширины, а затем сброса атрибутов метатега viewport. он выглядел бы примерно так:

    
      
    

    

1 ответ

Это происходит потому, что в вашем рабочем процессе нет ничего асинхронного, когда закомментировано Sleep.

Все полностью синхронно, но поскольку оно закодировано в вычислительном выражении async, оно становится странным образом вложенным. Видите, каждая строка let! фактически вызывает все, что находится справа (в вашем примере - workAsync), и передает ей обратный вызов, который должен быть вызван после выполнения асинхронной части. Обратный вызов содержит остальную часть кода - продолжение, начинающееся сразу после строки let!. Компилятор выполняет умные преобразования в коде, чтобы он выглядел все красиво и линейно, тогда как на самом деле это серия обратных вызовов.

Однако, поскольку workAsync на самом деле не асинхронный, он просто сразу вызывает обратный вызов, и обратный вызов поворачивается и вызывает следующую итерацию workAsync, и так далее. И поэтому ваш стек растет.

1114 Но подожди! Это на самом деле не должно расти в конце концов. Вызов обратного вызова является последним вызовом в workAsync, также называемом «хвостовым вызовом», и и .NETCore, и .NET Framework их устраняют (и действительно: на моей машине я не могу воспроизвести ваш результат). Единственное предположение, которое я могу предложить, это то, что вы должны запустить это на Mono, что не всегда устраняет хвостовые вызовы.

Однако, если вы раскомментируете Sleep, это становится переломным моментом. Sleep является на самом деле асинхронным, что означает, что он планирует выполнение обратного вызова в новом потоке после истечения времени ожидания. Это выполнение начинается с нуля, со свежим стеком, и поэтому стек не растет, даже если хвостовые вызовы не исключены.

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

0
ответ дан Fyodor Soikin 19 January 2019 в 17:49
поделиться
Другие вопросы по тегам:

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