WCF Callback Doblocks даже с «iSineynchronInationContext = False» -- c# поле с участием .net поле с участием wcf поле с участием thread-synchronization поле с участием wcf-callbacks пол Связанный проблема

WCF Callback Deadlocks Even With 'UseSynchronizationContext = false'


1
vote

проблема

русский

Я застрял с проблемой, которую я не могу понять.

Проблема связана с синхронизацией между потоками на стороне клиента, но я не могу найти корневую причину этого. Я создал небольшую демо, чтобы имитировать проблему, поэтому будет легче объяснить.

<Сильные> Сервисный контакт:

 <код> [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ITestServiceCallback))] public interface ITestService {     [OperationContract]     Task RegisterAsync();      [OperationContract]     Task UnRegisterAsync();      [OperationContract]     int Test1(int i); }   

Контракт обратного вызова:

 <код> public interface ITestServiceCallback {     [OperationContract(IsOneWay = true)]     void TestCallback(int value); }   

<Сильные> Реализация услуг:

Сервис при вызове <код> Test1 Метод будет поднять обратный вызов со значением, прилагаемом к <код> Test1

 <код> [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)] public class TestService : ITestService {     private readonly HashSet<ITestServiceCallback> _callbacks = new HashSet<ITestServiceCallback>();      public Task RegisterAsync()     {         Console.WriteLine("Registering Callback, Thread: {0}", Thread.CurrentThread.ManagedThreadId);         var callbackProxy = OperationContext.Current.GetCallbackChannel<ITestServiceCallback>();         _callbacks.Add(callbackProxy);         return Task.CompletedTask;     }      public Task UnRegisterAsync()     {         Console.WriteLine("Unregistering Callback, Thread: {0}", Thread.CurrentThread.ManagedThreadId);         var callbackProxy = OperationContext.Current.GetCallbackChannel<ITestServiceCallback>();         bool removed = _callbacks.Remove(callbackProxy);         Console.WriteLine("Callback was{0} successfully removed", removed ? "" : " not");         return Task.CompletedTask;     }      public int Test1(int i)     {         Console.WriteLine("Working on server, Test1, Thread: {0}", Thread.CurrentThread.ManagedThreadId);         Thread.Sleep(500);          raiseCallback(i);          Console.WriteLine("Finished on server, Test1, Thread: {0}", Thread.CurrentThread.ManagedThreadId);          return i;     }      private void raiseCallback(int value)     {         foreach (var callback in _callbacks)         {             try             {                 callback.TestCallback(value);             }             catch (Exception ex)             {                 Console.WriteLine("Callback calling failed in server: {0}", ex);             }         }     } }   

Клиентский код:

Клиент впервые регистрируется на обратные вызовы сервера (обратите внимание на вызов async Regional - это проблема ) Затем звонит <код> Test1 . Здесь вызов <код> Test1 никогда не возвращается

 <код> var callBack = new ClientCallback(); var client = DuplexChannelFactory<ITestService>.CreateChannel(callBack, _defaultBinding, _defaultEndpointAddress); using (client as IDisposable)             {                 await client.RegisterAsync(); // client.RegisterAsync.Wait();                 Console.WriteLine("Client Thread: {0}", Thread.CurrentThread.ManagedThreadId);                 try                 {                     int res = client.Test1(5);                     Console.WriteLine("Test1 was called, Server Result: {0}", res);                   }                 finally                 {                     await client.UnRegisterAsync();                 }             }     [CallbackBehavior(UseSynchronizationContext = false)]     class ClientCallback : ITestServiceCallback     {         public void TestCallback(int value)         {             Console.WriteLine("Callback Called, Value: {0}, Thread: {1}", value, Thread.CurrentThread.ManagedThreadId);         }     }   
    .
  • при звонке <код> RegisterAsync синхронно (с помощью <код> .Wait() ) вызов к <код> public interface ITestServiceCallback { [OperationContract(IsOneWay = true)] void TestCallback(int value); } 0 не тупик.
  • Вызов public interface ITestServiceCallback { [OperationContract(IsOneWay = true)] void TestCallback(int value); } 1 пропускает на сервере без какой-либо проблемы.
  • Используемая привязка - netnamedpipebinding:

    Привязка _defaultbinding = новый netnameedpipebinding { Maxbuffersize = int.maxvalue, Maxreceedmessagesize = int.maxvalue, Получатель = TimeSpan.maxvalue, Sendimeout = timespan.maxvalue, Closeetimeout = timespan.maxvalue. };

Я думал, что при настройке <код> public interface ITestServiceCallback { [OperationContract(IsOneWay = true)] void TestCallback(int value); } 2 свойства public interface ITestServiceCallback { [OperationContract(IsOneWay = true)] void TestCallback(int value); } 3 (как в <код> public interface ITestServiceCallback { [OperationContract(IsOneWay = true)] void TestCallback(int value); } 4 и в <код> public interface ITestServiceCallback { [OperationContract(IsOneWay = true)] void TestCallback(int value); } 5 ) должен решить эту проблему.

Английский оригинал

I am stuck with a problem that I can't quite understand.

The problem is related to synchronization between threads on the client side but I can't find the root cause of this. I created a small demo to simulate the problem, so it will be easier to explain.

Service Contact:

[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ITestServiceCallback))] public interface ITestService {     [OperationContract]     Task RegisterAsync();      [OperationContract]     Task UnRegisterAsync();      [OperationContract]     int Test1(int i); } 

Callback Contract:

public interface ITestServiceCallback {     [OperationContract(IsOneWay = true)]     void TestCallback(int value); } 

Service Implementation:

The service upon calling Test1 method will raise the callback with the value supplied to Test1 method.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)] public class TestService : ITestService {     private readonly HashSet<ITestServiceCallback> _callbacks = new HashSet<ITestServiceCallback>();      public Task RegisterAsync()     {         Console.WriteLine("Registering Callback, Thread: {0}", Thread.CurrentThread.ManagedThreadId);         var callbackProxy = OperationContext.Current.GetCallbackChannel<ITestServiceCallback>();         _callbacks.Add(callbackProxy);         return Task.CompletedTask;     }      public Task UnRegisterAsync()     {         Console.WriteLine("Unregistering Callback, Thread: {0}", Thread.CurrentThread.ManagedThreadId);         var callbackProxy = OperationContext.Current.GetCallbackChannel<ITestServiceCallback>();         bool removed = _callbacks.Remove(callbackProxy);         Console.WriteLine("Callback was{0} successfully removed", removed ? "" : " not");         return Task.CompletedTask;     }      public int Test1(int i)     {         Console.WriteLine("Working on server, Test1, Thread: {0}", Thread.CurrentThread.ManagedThreadId);         Thread.Sleep(500);          raiseCallback(i);          Console.WriteLine("Finished on server, Test1, Thread: {0}", Thread.CurrentThread.ManagedThreadId);          return i;     }      private void raiseCallback(int value)     {         foreach (var callback in _callbacks)         {             try             {                 callback.TestCallback(value);             }             catch (Exception ex)             {                 Console.WriteLine("Callback calling failed in server: {0}", ex);             }         }     } } 

The Client Code:

The client is first registering to the server's callbacks (note the async register call - This is the problem) Then calls Test1. here the call to Test1 never returns

var callBack = new ClientCallback(); var client = DuplexChannelFactory<ITestService>.CreateChannel(callBack, _defaultBinding, _defaultEndpointAddress); using (client as IDisposable)             {                 await client.RegisterAsync(); // client.RegisterAsync.Wait();                 Console.WriteLine("Client Thread: {0}", Thread.CurrentThread.ManagedThreadId);                 try                 {                     int res = client.Test1(5);                     Console.WriteLine("Test1 was called, Server Result: {0}", res);                   }                 finally                 {                     await client.UnRegisterAsync();                 }             }     [CallbackBehavior(UseSynchronizationContext = false)]     class ClientCallback : ITestServiceCallback     {         public void TestCallback(int value)         {             Console.WriteLine("Callback Called, Value: {0}, Thread: {1}", value, Thread.CurrentThread.ManagedThreadId);         }     } 
  • When calling RegisterAsync synchronously (using .Wait()) the call to Test1 does not deadlock.
  • The call for Test1 passes in the server without any problem.
  • The binding used is NetNamedPipeBinding:

    Binding _defaultBinding = new NetNamedPipeBinding { MaxBufferSize = int.MaxValue, MaxReceivedMessageSize = int.MaxValue, ReceiveTimeout = TimeSpan.MaxValue, SendTimeout = TimeSpan.MaxValue, CloseTimeout = TimeSpan.MaxValue };

I thought that when setting UseSynchronizationContext property to false (in both the ServiceBehaviourAttribute and in CallbackBehaviourAttribute) should solve this issue.

</div
              
     
     

Список ответов

Связанный проблема

5  сериализовать два разных экземпляра в списке на одну строку JSON  ( Serialize two different instances in a list to a single json string ) 
У меня есть два типа классов: <код> public class HolidayClass { public int ID { get; set; } public string Name { get; set; } public DateTime Sta...

9  DataTable не выпускает память  ( Datatable does not release memory ) 
У меня есть процесс загрузки данных, который загружает большую сумму данных в DataTable, затем выполняет некоторые данные, но каждый раз, когда задание заверш...

0  Написание одного символа за раз в приложении консоли C #?  ( Writing one character at a time in a c sharp console application ) 
Я не уверен, как это объяснить ... В основном я хочу иметь возможность писать строки текста в консоли, как старые RPG, используемые для записи диалога, один...

0  Не читайте текстовые данные на таблицу SQL в C #  ( Not reading text data to sql table in c sharp ) 
Поэтому я следовал большему количеству помощи, которую я мог найти здесь. Я создал программу C #, которая читает из текстового файла и вставляет в таблицу баз...

0  Как загрузить каталог на FTP, используя ftplib?  ( How to upload directory to ftp using ftplib ) 
У меня проблемы с загрузкой Все файлы на FTP: я использую ftplib . У меня есть функция для загрузки: <код> Proj executable not found. Please set PROJ_DIR v...

1  Visual Studio C # KeyDown блокирует друг друга  ( Visual studio c sharp keydown blocking each other ) 
Есть ли способ сделать два ключа работать одновременно, поэтому они не блокируют друг друга? <код> private void multiplayer_KeyDown(object sender, KeyEv...

0  Соединение не было закрыто. Текущее состояние соединения открыто  ( Connection was not closed connections current state is open ) 
Это дает сообщение об ошибках не было закрыто. Текущее состояние соединения открыто. Пожалуйста, помогите с кодом. <код> private void comboBox1_SelectedIn...

3  C # PropertiveGrid Drag Drop  ( C sharp propertygrid drag drop ) 
Я пытаюсь реализовать поддержку перетаскивания / падения на свойств в C # с использованием VS2005 (.NET 2.0). Собственность могут обрабатывать драгерацию и т....

0  Сообщение об ошибке Wile пытается открыть файл .xls  ( Error message wile trying to open xls file ) 
Я создаю файл Excel на лету для отправки его вложение в электронном письме. Соответствующий фрагмент кода приведен ниже (это консольное приложение) <код> pu...

0  Создание ссылки IPC между плагинами APC Java и C #  ( Establishing ipc link between a java app and c based plugins ) 
У нас есть приложение Java, а также ряд плагинов C #, для других приложений (например, Excel), которые могут взаимодействовать с основным приложением. Слой св...

5  Использование Litjson в Unity3D  ( Using litjson in unity3d ) 
2 вопроса. 1) Можно ли использовать библиотеку Litjson AS так же, как и сценарии в JavaScript? Это действительно общий вопрос о том, чтобы иметь возможность...

1  Получение релевантности упорядоченный результат из текстового запроса на коллекции MongoDB с использованием драйвера C #  ( Retrieve relevance ordered result from text query on mongodb collection using th ) 
Я пытаюсь отправить текстовые запросы коллекции и получить результаты в текстовом порядке. документы объяснить довольно хорошо, как это сделать в оболочке: ...

1  Получение строки сразу после вставки возвращается нет результата  ( Getting row right after insert returns no result ) 
Я бегут тесты подразделения, и когда я пытаюсь вставить данные в базу данных и получить его сразу после того, как я ничего не получаю (я пробовал с <код> Data...

2  Несколько клиентских проектов на один серверный проект W / Silverlight & Ria Services Beta  ( Multiple client projects to one server project w silverlight ria services bet ) 
Тип или имя пространства имен «Ресурсы» не существует в «MyWebProject.Web» (Вы пропустите сборку Ссылка?) C: users ... mysecondproject generated_...

0  Анимация спрайты в XNE после мыши  ( Sprite animation in xna following the mouse ) 
Моя старая проблема заключалась в том, что мой код изначально следит за мышью, но когда она достигла мыши, она исчезла, и в конечном итоге исчезла. Моя теку...

Связанный проблема

5  сериализовать два разных экземпляра в списке на одну строку JSON 
9  DataTable не выпускает память 
0  Написание одного символа за раз в приложении консоли C #? 
0  Не читайте текстовые данные на таблицу SQL в C # 
0  Как загрузить каталог на FTP, используя ftplib? 
1  Visual Studio C # KeyDown блокирует друг друга 
0  Соединение не было закрыто. Текущее состояние соединения открыто 
3  C # PropertiveGrid Drag Drop 
0  Сообщение об ошибке Wile пытается открыть файл .xls 
0  Создание ссылки IPC между плагинами APC Java и C # 
5  Использование Litjson в Unity3D 
1  Получение релевантности упорядоченный результат из текстового запроса на коллекции MongoDB с использованием драйвера C # 
1  Получение строки сразу после вставки возвращается нет результата 
2  Несколько клиентских проектов на один серверный проект W / Silverlight & Ria Services Beta 
0  Анимация спрайты в XNE после мыши 



© 2021 www.qaru.top All Rights Reserved. Q&A House все права защищены


Licensed under cc by-sa 3.0 with attribution required.