WCF InstanceContextMode. Несколько проблем

Итак, я размещаю службу 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)

Решение

Похоже, вы хотите установить это

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

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

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

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

[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
    }
}

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