WCF InstanceContextMode. Множественные проблемы - PullRequest
4 голосов
/ 27 февраля 2009

Итак, я размещаю сервис WCF в приложении WinForms. У меня есть следующее

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
         InstanceContextMode = InstanceContextMode.PerCall)]
public class Test : ITest
{
    public string TestIt(string input)
    {
        Thread.Sleep(5000);
        return "test";
    }
}

Я использую именованные каналы и у меня есть два экземпляра другого приложения, которые действуют как клиенты для вышеуказанной службы WCF (работающей в приложении WinForms). На основании настройки ConcurrencyMode для Multiple я подумал, что, когда Client1 вызывает тестовую службу, Client2 не должен ждать завершения первого вызова. Однако, когда Client1 вызывает TestIt, Client2 блокируется до тех пор, пока не будет завершен вызов от Client1!?!?! Разве он не должен каждый раз создавать новый экземпляр на основе вышеуказанных настроек?

Кроме того, лучший способ сохранить отзывчивым приложение WinForms, на котором размещается служба WCF, - это запустить службу WCF в отдельном потоке?

ПРИМЕЧАНИЕ. Установка [CallbackBehavior (UseSynchronizationContext = false)] в классе Test не устраняет проблему. Служба по-прежнему отвечает только на один запрос за раз.

Ответы [ 3 ]

10 голосов
/ 27 февраля 2009

Звучит так, как будто вы хотите установить

http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.usesynchronizationcontext.aspx

в ложь. По умолчанию, если есть контекст синхронизации, когда происходит service.Open (), WCF подберет его и будет использовать. Но если вы не хотите эту функцию, этот флаг, как отключить его.

4 голосов
/ 27 февраля 2009

После более подробного изучения единственного способа, которым я смог заставить это работать должным образом, было запустить ServiceHost в отдельном потоке в приложении WinForms. Если вы этого не сделаете, установка атрибутов ConcurrencyMode и InstanceContextMode ничего не даст.

1 голос
/ 01 апреля 2012

У меня была такая же проблема.

Мой класс, который реализовал Callback, также содержал методы для клиента wcf, поэтому, когда я вызывал какой-то метод из удаленной службы, а служба вызывала метод Callback, я создавал тупик.

[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class AppContext : ICustomerOrderCallback
{
    //WCF Proxy client
    private CustomerOrderClient _client = null;

    public AppContext()
    {
        InstanceContext context = new InstanceContext(this); 
        _client = new CustomerOrderClient(context);
        _client.Subscribe();  //Remote method for subscribing callback
    }

    public void SendMessage(string message)
    {
        //Calling Remote method 
        _client.SendMessage(message);
    }

    //....code

    //callback method
    public void OnMessageReceived(string message)
    {
        //.....code
    }
}

Поэтому я создал отдельный класс для обратного вызова, добавил к нему атрибут CallBehavior, и все заработало.

public class AppContext
{
    private CustomerOrderClient _client = null;

    private MyCallbackClass _myCallback = null;
    public AppContext()
    {
        _myCallback = new MyCallbackClass();
        InstanceContext context = new InstanceContext(_myCallback); 
        _client = new CustomerOrderClient(context);
        _client.Subscribe();
    }

    public void SendMessage(string message)
    {
        _client.SendMessage(message);
    }
}

[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyCallbackClass : ICustomerOrderCallback
{
    public void OnMessageReceived(string message)
    {
        //.....code
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...