Вы задали несколько вопросов в своем вопросе. Я сломаю их немного иначе, чем ты. Но сначала позвольте мне прямо ответить на вопрос.
Мы все хотим, чтобы камера была легкой, качественной и дешевой, но, как гласит поговорка, вы можете получить только два из этих трех. Вы находитесь в такой же ситуации здесь. Вы хотите эффективное решение, безопасное и разделяющее код между синхронными и асинхронными путями. Вы получите только два из них.
Позвольте мне объяснить, почему это так. Мы начнем с этого вопроса:
Я видел, что люди говорят, что вы можете использовать GetAwaiter().GetResult()
для асинхронного c метода и вызывать его из вашего метода syn c? Является ли этот поток безопасным во всех сценариях ios?
Смысл этого вопроса состоит в том, «могу ли я разделить синхронные и асинхронные пути, заставив синхронный путь просто выполнить синхронное ожидание в асинхронной версии? "
Позвольте мне быть предельно ясным по этому вопросу, потому что это важно:
ВЫ НЕМЕДЛЕННО ОСТАНОВИТЕСЬ, ЧТОБЫ СОВЕТАТЬ С НИХ ЛЮДЕЙ .
Это очень плохой совет. Очень опасно синхронно извлекать результат из асинхронной задачи , если только у вас нет доказательств того, что задача была выполнена нормально или ненормально .
Причина, по которой это чрезвычайно плохой совет, - хорошо, рассмотрим этот сценарий. Вы хотите косить газон, но лезвие вашей газонокосилки сломано. Вы решили следовать этому рабочему процессу:
- Заказать новый блейд с веб-сайта. Это асинхронная операция с высокой задержкой.
- Синхронное ожидание - то есть режим сна, пока у вас не будет блейд в руке .
- Периодически проверяйте почтовый ящик, чтобы увидеть если лезвие прибыло.
- Снимите лезвие с коробки. Теперь он у вас в руках.
- Установите нож в газонокосилку.
- Косите газон.
Что происходит? Вы спите вечно, потому что операция проверки почты теперь стробируется на том, что происходит после того, как почта приходит .
Это чрезвычайно просто чтобы попасть в эту ситуацию, когда вы синхронно ожидаете произвольное задание. Эта задача может иметь запланированную работу в будущем потока, который сейчас ожидает , и теперь это будущее никогда не наступит, потому что вы ожидаете его.
Если вы выполните асинхронное ожидание тогда все нормально! Вы периодически проверяете почту, и пока вы ждете, вы делаете бутерброд или платите налоги или что-то еще; Вы продолжаете выполнять работу, пока ждете.
Никогда не ждите синхронно. Если задача выполнена, это ненужно . Если задача не выполнена, но запланирована на запуск из текущего потока, это неэффективно , поскольку текущий поток может обслуживать другую работу вместо ожидания. Если задача не выполнена и расписание запускается в текущем потоке, висит , чтобы синхронно ждать. Нет веских оснований для синхронного ожидания, опять же, , если только вы уже не знаете, что задача выполнена .
Подробнее о данной теме c см.
https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
Стивен объясняет сценарий реального мира гораздо лучше, чем я.
Теперь давайте рассмотрим «другое направление». Можем ли мы поделиться кодом, сделав асинхронную версию просто выполняющей синхронную версию в рабочем потоке?
Это , возможно и действительно , вероятно плохая идея, для следующего причины.
Неэффективно, если синхронная операция является работой ввода-вывода с высокой задержкой. По сути, это нанимает работника и заставляет этого работника спать , пока задача не будет выполнена. Нитки безумно дорогие . По умолчанию они потребляют минимум миллион байтов адресного пространства, им требуется время, они берут ресурсы операционной системы; Вы не хотите прожечь нить, делая бесполезную работу.
Возможно, синхронная операция не записана как поточно-ориентированная.
Этот является более разумным методом, если Работа с высокой задержкой связана с процессором, но если это так, вы, вероятно, не хотите просто передавать ее в рабочий поток. Вы, вероятно, захотите использовать библиотеку параллельных задач, чтобы распараллелить ее как можно большему количеству процессоров, вы, вероятно, захотите отменить logi c, и вы не можете просто заставить синхронную версию делать все это, потому что тогда это будет уже асинхронная версия .
Дополнительная литература; опять же, Стивен объясняет это очень четко:
Почему бы не использовать Task.Run:
https://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-using.html
More "делай и не делай" "Scenar ios для Task.Run:
https://blog.stephencleary.com/2013/11/taskrun-etiquette-examples-dont-use.html
Что же нас тогда оставит? Оба метода для совместного использования кода приводят либо к тупикам, либо к большой неэффективности. Мы пришли к выводу, что вы должны сделать выбор. Вам нужна программа, которая является эффективной и правильной и доставляет удовольствие вызывающей стороне, или вы хотите сохранить несколько нажатий клавиш, дублируя небольшой объем кода между синхронным и асинхронным путями? Боюсь, вы не получите и то, и другое.