2012-02-17 2 views
1

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

В GUI-приложении есть две кнопки и индикатор выполнения. enter image description here

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

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

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

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

Все это кажется хорошим.

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

Это выглядит как вопрос распараллеливания.

Так кажется, что если я начну с нажатия кнопки печати, тогда все будет работать. Но если я начну с нажатия кнопки запуска, то будет мертвый замок. Почему?

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

ответ

1

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

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

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

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

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

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

worker2.Print(); 
+0

спасибо, открывающее множественные соединения работы. – CuiPengFei

+0

, мы также можем решить эту проблему, выполнив задачу в другом потоке. – CuiPengFei

Смежные вопросы