Правильный способ начать и asyn c звонить и забыть? - PullRequest
1 голос
/ 20 апреля 2020

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

Как правильно это сделать? Мне нужно это как в. NET Framework 4.6, так и в .NETCore 2, если есть различия.

public async Task<MyResult> DoWorkAsync(){...}

public void StarterA(){
    Task.Run(() => DoWorkAsync());
}

public void StarterB(){
    Task.Run(async () => await DoWorkAsync());
}

Это один из этих двух или что-то другое / лучше?

// edit: в идеале без каких-либо дополнительных библиотек.

Ответы [ 2 ]

2 голосов
/ 20 апреля 2020

Как правильно сделать это?

Сначала вам нужно решить, действительно ли вы хотите запустить и забыть . По моему опыту, около 90% людей, которые просят об этом, на самом деле не хотят , хотят пожара и забывания; им нужна служба фоновой обработки.

В частности, «забыть» означает:

  1. Вам все равно, когда действие завершится.
  2. Вы не не волнует, есть ли исключения при выполнении действия.
  3. Вам все равно, завершит ли действие вообще .

Так что в реальном мире Случаи использования «забей и забудь» поразительно малы. Действие, такое как обновление кэша на стороне сервера, будет в порядке. Отправка электронных писем, создание документов или что-нибудь связанных с бизнесом не ОК, потому что вы (1) хотите, чтобы действие было завершено, и (2) получили уведомление, если действие имело ошибка.

В подавляющем большинстве случаев люди вообще не хотят огня и забывания; они хотят сервис фоновой обработки. Правильный способ построить один из них - добавить надежную очередь (например, Azure Queue / Amazon SQS или даже базу данных) и создать независимый фоновый процесс (например, Azure Function / Amazon Lambda /. NET Базовая служба BackgroundService / Win32), обрабатывающая эту очередь. По сути, это то, что предоставляет Hangfire (использование базы данных для очереди и запуск фонового процесса в-pro c в ASP. NET процессе).

Является ли он одним из эти два или что-то другое / лучше?

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

Однако в этом конкретном c случае - когда async лямбда вызывает только один метод - исключение async и await в порядке.

2 голосов
/ 20 апреля 2020

Это зависит от того, что вы подразумеваете под правильным:)

Например: вас интересуют исключения, которые выдается в ваших вызовах «запусти и забудь»? Если нет, то это нормально. Хотя вам может понадобиться подумать о том, в какой среде находится задача.

Например, если это приложение asp. net, и вы делаете это во время жизни потока, созданного из-за вызов в .aspx или .sv c. Задача становится фоновым потоком этого (переднего плана) потока. Поток переднего плана может быть очищен пулом приложений до того, как ваша задача «запустить и забыть» завершена.

Так что подумайте также о том, в каком потоке живут ваши задачи.

Думаю, эта статья дает Вот вам некоторая полезная информация: https://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx

Также обратите внимание, что если вы не вернете значение в своих Задачах, задача не вернет информацию об исключении. Источником для этого является справочник для Microsoft экзамен 70-483. Возможно, где-то есть бесплатная версия этого онлайн; P https://www.amazon.com/Exam-Ref-70-483-Programming-C/dp/0735676828

Может быть полезно знать, что если у вас есть Метод asyn c вызывается не-асин c, и вы sh узнаете его результат. Вы можете использовать .GetAwaiter (). GetResult ().

Также я считаю важным отметить разницу между asyn c и многопоточностью.

Asyn c только полезно, если есть операции, которые используют другие части компьютера, которые не являются процессором. Такие вещи, как работа в сети или операции ввода / вывода. Использование asyn c затем сообщает системе go вперед и использует мощность ЦП в другом месте, вместо того, чтобы «блокировать» этот поток в ЦП для ожидания ответа.

многопоточность - это распределение операции над разными потоками в ЦП (например, создание задачи, которая создает фоновый поток потока переднего плана ... потоки переднего плана, являющиеся потоками, составляющими ваше приложение, они являются первичными, существуют фоновые потоки, связанные с потоками переднего плана. Если Вы закрываете связанный поток переднего плана, фоновый поток также закрывается) Это позволяет процессору одновременно выполнять разные задачи.

Объединение этих двух компонентов гарантирует, что процессор не будет заблокирован только в 4 потоках. если это 4-х потоковый процессор. Но он может открывать больше, пока он ожидает асин c задач, ожидающих операций ввода-вывода.

Я надеюсь, что это даст вам информацию, необходимую для выполнения, чем бы вы ни занимались:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...