2012-01-17 32 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

相關問題