Межпроцессное взаимодействие с именованным каналом и службой WCF: проблема потоков - PullRequest
1 голос
/ 18 февраля 2012

У меня есть два процесса: один GUI, другой CUI.Каждый из них содержит простую службу WCF и связывается друг с другом по именным каналам.

В приложении с графическим интерфейсом есть две кнопки и индикатор выполнения.enter image description here

Кнопка «Начать выполнение» сообщает CUI запустить задачу в течение 30 секунд.CUI сообщает о своем прогрессе обратно в графический интерфейс, поэтому индикатор выполнения может быть обновлен.Кнопка «Печать» указывает CUI напечатать строку.

Теперь, если мы несколько раз нажмем кнопку «Печать», все в порядке, CUI будет печатать строки: enter image description here

Затем, если я нажму кнопку «начать работу», CUI напечатает прогресс на консоль и сообщит о ходе выполнения обратно в графический интерфейс, а индикатор выполнения будет обновлен: enter image description here

Затем я могу нажатьКнопка «Печать» еще пару раз, и она работает: enter image description here

Все это выглядит хорошо.

Но если я перезапущу эти два процесса и нажму кнопку «Начать выполнение»затем нажмите кнопку «Печать», затем оба процесса будут заморожены: enter image description here

Это выглядит как проблема с многопоточностью.

Так что, похоже, я начинаю с нажатия кнопки печатиКнопка, то все работает.Но если я начну с того, что нажму кнопку «Запустить запуск», то появится мертвая блокировка.Почему это так?

Вы можете скачать этот образец здесь: http://files.cnblogs.com/cuipengfei/SampleForStackOverflow.zip

1 Ответ

1 голос
/ 18 февраля 2012

Деблокировка появляется при вызове worker.Print (), поскольку она не создает новый объект для работника, но пытается повторно использовать тот же объект.Если вы поместите этот вызов в другой поток, то увидите, что этот вызов выполняется после завершения worker.RunTask (30).

Сначала я подумал об изменении InstanceContextMode.Single на InstanceContextMode.PerCall, поэтому он создаетодин объект на вызов вместо использования одного и того же объекта для всех вызовов.Это не решило проблему.

Повторно протестируйте предоставленное вами тематическое исследование, оно также будет работать, если вы позволите закончить worker.RunTask (30).Поэтому я думаю, что проблема возникает, если вы никогда не завершали вызов до вызова 2-го вызова.Затем он пытается повторно использовать тот же экземпляр сервера.После того, как вы полностью завершили один вызов, он работает, как и ожидалось.

Однако ваша проблема заключается в том, чтобы открыть несколько соединений с вашим сервером:

NetNamedPipeBinding binding2 = new NetNamedPipeBinding();
worker2 = ChannelFactory<IWorker>.CreateChannel(binding2, endpointAddress);

Затем используйте это для доступа к операции печати.:

worker2.Print();
...