.NET Задачи, которые ждут работы
Я хочу создать на сервере темы, которые ждут работы. Я хочу 1 поток на пользователя, который посещает сайт. Это работает, создавая цикл while с thead.sleep(100), но это кажется неэффективным. Мы отслеживаем каждую задачу, которая принадлежит каждому посетителю, чтобы мы могли получить доступ к их объектам, связанным с winform.
Таким образом, нам нужны потоки, потому что мы потратили много лет на winforms, а большая часть кода находится в коде позади форм, поэтому мы должны запустить экземпляр MainForm для каждого пользователя и сохранить его в памяти, пока пользователь посещает сайт. Интерфейс html довольно тупой и просто реагирует на сигналы, которые предоставляет наш сокет (например, открывающийся ящик сообщений или маленькие формы). Например, для окна сообщения (да / нет) сервер должен дождаться выбора пользователя, прежде чем продолжить процесс.
Первоначальный плохой дизайн заставляет нас использовать этот подход, который работает и работает быстро. Я только хочу заменить циклы ожидания чем-то лучшим (проще / быстрее). Мы не можем полностью переделать его, так как на его разработку потребуется 1 год.
Может быть, rx.NET может помочь, но я не знаю этого.
Здесь есть соответствующий ответ, но он неочевиден.
Спасибо
Феликс
1 ответ
Поправьте меня, если я неправильно читаю ваш вопрос, но, насколько я понимаю, когда пользователи выполняют рассматриваемый вызов, это предполагает какой-то потенциально длительный ввод-вывод.
Потоки не являются хорошим выбором, если все, что вы делаете, ждет какого-то результата. Создание дополнительных потоков в основном хорошо для работы с процессором, но преимущество их использования гораздо менее очевидно, если все, что вы делаете, ждет, когда что-то произойдет.
Вам действительно нужно заменить это каким-то асинхронным или неблокирующим вводом / выводом.
Моя стандартная иллюстрация этого факта такова: предположим, вы идете в ресторан на 10 человек. Когда приходит официант, первый человек, которого он спрашивает о своем заказе, не готов; Тем не менее, остальные 9 человек. Таким образом, официант спрашивает другие 9 человек для их заказов и затем возвращается к оригинальному парню, надеясь, что он будет готов сделать заказ к тому времени. (Это определенно не тот случай, когда они получат второго официанта, который будет ждать, пока оригинальный парень будет готов сделать заказ, и, вероятно, в любом случае это не сэкономит много времени). Вот как во многих случаях работает async / await (за исключением того, что некоторые из вызовов библиотеки Task Parallel, например Thread.Run(...), на самом деле выполняются в других потоках - на нашей иллюстрации - второй официант), поэтому убедитесь, что вы проверите документацию, для которой есть).
Случай, когда вам нужно несколько официантов, относится к задачам, которые действительно "привязаны к официанту" (т. Е. Когда официант будет основной задержкой для этой задачи). Например, если в вашем ресторане 100 столов, было бы неразумно, чтобы один официант пытался обслужить их всех, и не было бы разумно также, чтобы официант также готовил еду, как только он получит заказы. В этих случаях вам понадобится отдельный человек для приготовления пищи и несколько официантов. В конце концов, вам может понадобиться несколько поваров, а может и автобусы и т. Д. Это тот случай, когда у вас будет несколько потоков; как правило, потоки будут выполнять специализированные роли (например, официанты, автобусы, повара и т. д.) и будут "делить" работу, которая соответствует их конкретной категории (например, каждый официант будет работать с несколькими таблицами).
Однако для вашего конкретного приложения, даже если вы создаете новый поток для обработки каждого пользователя, есть гораздо лучшие способы сделать то, что вы хотите, чем непрерывный опрос результатов с использованием while
а также Thread.Sleep
например, класс ManualResetEvent, который позволяет блокировать поток (или группу потоков) до тех пор, пока не произойдет конкретное событие (что устраняет необходимость в цикле опроса).