.NET Framework Developer Center >
.NET Development Forums
>
Windows Communication Foundation
>
Strange WCF behavior
Strange WCF behavior
- Hello,I have a simple Wcf service, which sends a message to clients every 700 seconds. Client also has an ability to recieve a message from the serverThe Server:
ServiceContract[ServiceContract(CallbackContract = typeof(IClientCallback))] public interface ISampleService { [OperationContract(IsOneWay = true)] void RegisterClient(); [OperationContract(IsOneWay = true)] void UnregisterClient(); [OperationContract] String RecieveString(); }
Callback contract:[ServiceContract] public interface IClientCallback { [OperationContract(IsOneWay = true)] void NewMessage(String message); }Service implementation[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] public class SampleService : ISampleService { private List<IClientCallback> _Callbacks = new List<IClientCallback>(); private object lockCallbacks = new object(); private Timer _TimerCallbacks; public SampleService() { _TimerCallbacks = new Timer(OnTimer, null, 0, 700); } // timer callback public void OnTimer(object state) { lock (lockCallbacks) { for (int i = 0; i < _Callbacks.Count; i++) try { _Callbacks[i].NewMessage(String.Format("Client callback", DateTime.Now)); } catch (CommunicationException) { // channel faulted _Callbacks.RemoveAt(i); i--; } } } #region ISampleService Members public void RegisterClient() { OperationContext context = OperationContext.Current; IClientCallback c = context.GetCallbackChannel<IClientCallback>(); lock (lockCallbacks) _Callbacks.Add(c); } public void UnregisterClient() { OperationContext context = OperationContext.Current; IClientCallback c = context.GetCallbackChannel<IClientCallback>(); lock (lockCallbacks) _Callbacks.Remove(c); } public string RecieveString() { return "Client request"; } #endregion }This is the part where the server is createdSampleService instance = new SampleService(); ServiceHost host = new ServiceHost(instance); NetTcpBinding binding = new NetTcpBinding(SecurityMode.None); binding.MaxReceivedMessageSize = Int32.MaxValue; host.AddServiceEndpoint(typeof(ISampleService), binding, new Uri("net.tcp://localhost:888/SampleService")); // set all throttlings to maximum to ensure the problem is not here ServiceThrottlingBehavior bhvrThrottling = new ServiceThrottlingBehavior(); bhvrThrottling.MaxConcurrentCalls = Int32.MaxValue; bhvrThrottling.MaxConcurrentInstances = Int32.MaxValue; bhvrThrottling.MaxConcurrentSessions = Int32.MaxValue; host.Description.Behaviors.Add(bhvrThrottling); // mex host.Description.Behaviors.Add(new ServiceMetadataBehavior()); Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding(); host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, new Uri("net.tcp://localhost:888/SampleService/mex")); host.Open();
The Client:There are proxy was generated by Visual Studio and implementation of the callbackclass ServiceCallback : ISampleServiceCallback { #region ISampleServiceCallback Members public void NewMessage(string message) { Debug.WriteLine(message); } #endregion }
But here is the most fun part. I've got a code, that registers for server's messages and requests it manually every 700 ms.ServiceCallback service = new ServiceCallback(); SampleServiceClient client = new SampleServiceClient(new InstanceContext(service)); client.RegisterClient(); Debug.WriteLine("Connected..."); for (;;) { Debug.WriteLine(client.RecieveString()); Thread.Sleep(700); }
1) If i run this code in Console app it works fine
2) If i run this code in WinForm or WPF app it fails with TimeoutException on client.RecieveString()How can i solve this???The full code you can see here http://depositfiles.com/files/8wf6ywkahPS The Debug class is using
Answers
- the solution was found on another blog - codehelper.ru:All we have to do is to change ConcurrencyMode to Reetrant in ServiceBegavior for our SampleService and to set UseSynchronizationContext to false in CallbackBehavior for ServiceCallbackIt works fine for me
- Marked As Answer byGarF1eld Monday, November 09, 2009 2:14 PM
All Replies
- I still keep trying to manage this and i've found that if this code is run in a separate thread, it just works.Is this the way as it should be??? Is this because forms interface runs in a single thread?
ThreadPool.QueueUserWorkItem((s) => { ServiceCallback service = new ServiceCallback(); SampleServiceClient client = new SampleServiceClient(new InstanceContext(service)); client.RegisterClient(); Debug.WriteLine("Connected..."); for (; ; ) { Debug.WriteLine(client.RecieveString()); Thread.Sleep(700); } });Cmon, I extremely need a solution. Any advices how to avoid this? - It seems to be a bug, doesnt it?Is there reason to keep the service logic in separate thread???Can somebody help me? msft?
- the solution was found on another blog - codehelper.ru:All we have to do is to change ConcurrencyMode to Reetrant in ServiceBegavior for our SampleService and to set UseSynchronizationContext to false in CallbackBehavior for ServiceCallbackIt works fine for me
- Marked As Answer byGarF1eld Monday, November 09, 2009 2:14 PM


