Блокирующее приложение C# WCF NetTCPBinding

У меня есть базовое приложение типа buddylist, которое является сделкой pub/sub в WCF. Моя проблема заключается в том, что один или два вызова выполняются долго, и это блокирует все серверное приложение (обновления графического интерфейса пользователя и т. д.).

Вот мой код:

[ServiceContract(SessionMode = SessionMode.Required,
CallbackContract = typeof(IBuddyListContract))]
public interface IBuddyListPubSubContract
{
    [OperationContract]
    string GetABunchOfDataZipped(String sessionId); // this can take > 20 seconds

    ....
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, 
    ConcurrencyMode = ConcurrencyMode.Multiple)]
public class BuddyListPubSubContract : IBuddyListPubSubContract
{
    string GetABunchOfDataZipped(String sessionId)
    {
        // do some calculations and data retrival
        return  result;
    }
}

Пока у меня есть идея, как это сделать, но есть ли более простой способ?

Идея 1: пусть GetABunchOfDataZipped(String sessionId) будет недействительным, а когда он завершится, у меня будет другая конечная точка, которая находится в моем дуплексном контракте, который я нажал. Мне это не нравится, как будто это фундаментальное изменение в моей архитектуре, и если строка представляет собой большой блок текста при медленном подключении к Интернету, она по-прежнему будет страдать от той же проблемы?


person Luke Belbina    schedule 31.05.2011    source источник


Ответы (1)


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

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

person Joel C    schedule 31.05.2011
comment
В настоящее время я создаю ServiceHost прямо в своем потоке пользовательского интерфейса в событии загрузки. Вместо этого я должен создать его в фоновом потоке? - person Luke Belbina; 31.05.2011
comment
Также поведение блокировки находится на сервере. Клиент вызывает все методы внутри фонового потока. - person Luke Belbina; 31.05.2011
comment
@nextgenneo Если вы создадите свой ServiceHost в потоке пользовательского интерфейса, да, по умолчанию он будет обрабатывать запросы только в потоке пользовательского интерфейса. Однако вы можете установить [ServiceBehavior(UseSynchronizationContext=false)] в своем классе реализации службы, и это приведет к тому, что запросы будут обрабатываться рабочими потоками из пула потоков. См. code-magazine.com/article.aspx?quickid=0701041&page=3. для полного объяснения. - person Joel C; 01.06.2011