To achieve what you are looking for, you need to complete a callback contract in your service. Then your win-forms application will be able to "subscribe" to events running in the service (for example, changes to your object).
To do this, you execute a service contract with a callback contract:
[ServiceContract] public interface IMyService_Callback { [OperationContract(IsOneWay = true)] void NotifyClients(string message); } [ServiceContract(CallbackContract = typeof(IMyService_Callback))] public interface IMyService { [OperationContract] bool Subscribe(); }
Then you implement your service:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant)] public class MyService : IMyService { private List<IMyService_Callback> callbacks; public MyService() { this.callbacks = new List<IMyService_Callback>(); } private void CallClients(string message) { callbacks.ForEach(callback => callback.NotifyClients(message)); } public bool Subscribe() { var callback = OperationContext.Current.GetCallbackChannel<IMyService_Callback>(); if (!this.callbacks.Contains(callback)) { this.callbacks.Add(callback); }
In your winforms client, you need to implement a callback method:
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)] public partial class ServiceClient : Form, IMyService_Callback { // Sync context for enabling callbacks SynchronizationContext uiSyncContext; public ServiceClient() { InitializeComponent(); //etc. uiSyncContext = SynchronizationContext.Current; // Create proxy and subscribe to receive callbacks var factory = new DuplexChannelFactory<IMyService>(typeof(ServiceClient), "NetTcpBinding_IMyService"); var proxy = factory.CreateChannel(new InstanceContext(this)); proxy.Subscribe(); } // Implement callback method public void NotifyClients(string message) { // Tell form thread to update the message text field SendOrPostCallback callback = state => this.Log(message); uiSyncContext.Post(callback, "Callback"); } // Just updates a form text field public void Log(string message) { this.txtLog.Text += Environment.NewLine + message; } }
Service configuration:
<system.serviceModel> <services> <service name="TestService.MyService" behaviorConfiguration="Normal"> <endpoint address="net.tcp://localhost:8000/MyService" contract="TestService.IMyService" binding="netTcpBinding" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="Normal" > <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
Client Configuration
<system.serviceModel> <client> <endpoint address="net.tcp://localhost:8000/MyService" binding="netTcpBinding" contract="TestService.IMyService" name="NetTcpBinding_IMyService"> </endpoint> </client> </system.serviceModel>
source share