2012-01-17 35 views
4

我有一个不可序列化的对象,我想从一个单独的进程访问。我环顾四周,似乎唯一可行的选择是使用WCF,但我不确定如何做到这一点,因为我是新来的WCF。如果我创建了一个WCF服务,如何将WinForm“挂接”到WCF服务中的各种事件中?例如,用户直接与WCF服务进行通信,我希望我的WinForm客户端得到通知。我如何能够知道用户何时完成了WCF服务的某些操作,并让WinForm客户端了解了这一点?在另一个进程中处理WCF事件

+0

我想你应该尝试WCF全双工服务。但你将不得不创建一些逻辑来审计行为并将它们传输到你的winform应用程序 – 2012-01-17 05:44:22

+0

我不确定为什么使用WCF将允许你从另一个进程访问一个不可序列化的对象? – 2012-01-17 08:18:22

+0

@ShoaibShaikh - 我是新来的WCF,但看全双工,似乎它是用户和服务之间的合同。 WinForm客户端是第三方,不直接调用WCF服务。 – Skoder 2012-01-17 15:19:53

回答

10

实现您所寻找的一种方法是在您的服务上实施回调合同。然后,你的胜利形式的应用程序将能够“订阅”在服务上发起的事件(例如修改你的对象)。

要做到这一点,你实现了回调契约的服务合同:

[ServiceContract] 
public interface IMyService_Callback 
{ 
    [OperationContract(IsOneWay = true)] 
    void NotifyClients(string message); 
} 

[ServiceContract(CallbackContract = typeof(IMyService_Callback))] 
public interface IMyService 
{ 
    [OperationContract] 
    bool Subscribe(); 
} 

然后你实现你的服务:

[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; 
    } 
} 

在你的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; 
    } 
}  

配置服务:

<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> 

配置客户端

<system.serviceModel> 
    <client> 
    <endpoint address="net.tcp://localhost:8000/MyService" 
       binding="netTcpBinding" 
       contract="TestService.IMyService" 
       name="NetTcpBinding_IMyService"> 
    </endpoint> 
    </client> 
</system.serviceModel> 
+0

谢谢,这是一个很好的答案。 – Skoder 2012-01-17 16:04:13

+0

代码实际上并不工作 - 将尽快使用工作代码进行更新。但总的模式是正确的。 – 2012-01-17 16:24:07

+0

现在可以使用代码 - 必须在客户端上用DuplexChannelFactory替换ChannelFactory。 – 2012-01-17 16:55:57

相关问题