Как сделать сервис WCF STA (однопоточным)

У меня есть служба WCF, которая включает компоненты пользовательского интерфейса, что заставляет меня находиться в режиме STA.

Как установить сервисное поведение в режим STA?


Служба использует ссылку на файл DLL WPF, который открывает окно пользовательского интерфейса (используется как порт просмотра) для анализа изображений. Когда служба пытается создать экземпляр этого элемента (наследуется от окна), она выдает исключение:

Вызывающий поток должен быть STA

3 ответа

Я делаю что-то похожее на тебя.

Мое решение состояло в том, чтобы направить все вызовы через очередь потока STA. Я использовал потокобезопасную коллекцию из новой параллельной инфраструктуры для постановки в очередь действий, которые я хотел запустить в потоке STA. Затем у меня было количество потоков STA, которые постоянно проверяли очередь на наличие новых действий для выполнения.

Атрибут ServiceBehaviour позволяет вам указать поведение. В вашем случае для одного потока вы бы использовали следующее:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerCall)]
public class Service : IService
{
}

Возможно, вы захотите прочитать о разных InstanceContextModes, чтобы помочь вам лучше выбрать, как вы хотите, чтобы сервис вел себя.

Вы также должны добавить в свой app.config новое поведение сервиса (или редактирование существующего):

    <behavior name="wsSingleThreadServiceBehavior">
      <serviceThrottling maxConcurrentCalls="1"/>
    </behavior>

и в вашей конфигурации поведения в том же app.config установить поведение Configuration следующим образом:

 <service behaviorConfiguration="wsSingleThreadServiceBehavior" name="IService">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsEndpointBinding" name="ConveyancingEndpoint" contract="IService" />
  </service>

Надеюсь, это сэкономит вам время

Я бы исследовал использование атрибута [STAThread] для переключения потоковой модели. например

[STAThread]
static void Main()
{
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] { new Host() };
        ServiceBase.Run(ServicesToRun);
}

Описание атрибута STAThread

Но я запутался, почему вы вообще используете компоненты пользовательского интерфейса в веб-сервисе. Можете ли вы объяснить немного больше о том, почему вы пытаетесь это сделать?

Другие вопросы по тегам