Sko*_*der 4 c# wcf process wcf-client winforms
我有一个不可序列化的对象,我想从一个单独的进程访问.我环顾四周,似乎唯一可行的选择是使用WCF,但我不知道如何做到这一点,因为我是WCF的新手.如果我创建一个WCF服务,如何将WinForm"挂钩"到WCF服务中的各种事件中?例如,用户直接与WCF服务通信,我希望WinForm客户端得到通知.我怎么能知道用户何时使用WCF服务做了什么并让WinForm客户端接受了这个?
tom*_*ern 10
实现您正在寻找的方法是在您的服务上实现回调合同.然后,您的win-forms应用程序将能够"订阅"在服务上触发的事件(例如对对象的修改).
为此,您需要使用回调合同实现服务合同:
[ServiceContract]
public interface IMyService_Callback
{
[OperationContract(IsOneWay = true)]
void NotifyClients(string message);
}
[ServiceContract(CallbackContract = typeof(IMyService_Callback))]
public interface IMyService
{
[OperationContract]
bool Subscribe();
}
Run Code Online (Sandbox Code Playgroud)
然后,您实现您的服务:
[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);
}
// send a message back to the client
CallClients("Added a new callback");
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
在winforms客户端中,您只需要实现回调方法:
[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;
}
}
Run Code Online (Sandbox Code Playgroud)
配置服务:
<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>
Run Code Online (Sandbox Code Playgroud)
为客户配置
<system.serviceModel>
<client>
<endpoint address="net.tcp://localhost:8000/MyService"
binding="netTcpBinding"
contract="TestService.IMyService"
name="NetTcpBinding_IMyService">
</endpoint>
</client>
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)