2012-10-23 65 views
0

我有一個WCF服務,我試圖讓回調工作。回調幹擾回撥初始呼叫

所述接口類看起來像:

[ServiceContract(
    SessionMode = SessionMode.Required, 
    CallbackContract = typeof(IPredatorEngineCallback))] 
public interface IMyApplication 
{ 
    [OperationContract] 
    Boolean DoSomething(string mystring); 

    [OperationContract] 
    Boolean SubscribeToEvent(); 

} 

public interface IMyApplicationCallback 
{ 
    [OperationContract (IsOneWay = true)] 
    void EventRaised(EventMessage myEventMessage) 
} 

事件消息是類,這是在由服務器客戶機&共享的通訊科庫。

該接口的實現是這樣的:

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)] 
public class MyApplication : IMyApplication 
{ 
    private List<IMyApplicationCallback> CallbackList = new List<IMyApplicationCallback>; 

    public Boolean DoSomething(string mystring) 
    { 
      // Do stuff 

      // Now Raise an event 
      PublishEvent(); 

      return true; 
    } 

    public Boolean SubscribeToEvent() 
    {  
     IMyApplicationCallback IMAC = OperationContext.Current.GetCallbackChannel<IMyApplicationCallback>(); 
     if (!Callbacklist.Contains(IMAC) 
      Callbacklist.Add(IMAC); 
    } 

    private void PublishEvent() 
    { 
     EventMessage myEM = new EventMessage(); 

     // Populate myEM.Fields 

     Callbacklist.ForEach(delegate(IMyApplicationCallback callback) 
     { callback.EventRaised(myEM); }); 
    } 
} 

的想法是,客戶可以選擇訂閱接收事件。

我在分階段構建我的應用程序並立即執行回調之前,服務工作正常。對DoSomething()進行的調用做了他們應該做的事情,並立即返回。

現在我已經實現了CallBacks,如果我註釋掉DoSomething中的RaiseEvents()行,它會立即返回。

我的客戶端代碼現在先調用SubscribeToEvent(),然後再次調用DoSomething()。

如果我取消註釋並通過調試器進行操作,我會發現DoSomething幾乎立即就完成了 - 沒有任何延遲。我已經同時在VS2010上運行同一臺機器上的客戶端& WCF服務。我遵循DoSomething()中的結束語}。

但是,我的客戶端中的回調函數未被調用。 1分鐘後,終於有人打電話了,我也收到一條錯誤消息,說明我原來的電話已經超時。所以我改變的app.config減少爲10秒,該錯誤信息是:

"This request operation sent to http://localhost:8732/Design_Time_Addresses/MyApplication/MyAppication did not receive a reply in the configured timeout (00:00:09.987997). The time allotted to this operation may have been a portion of a longer timeout..." 

所以看來有物體擋住了第一個電話的回報;但事件已經提出,因爲它最終到達那裏。我懷疑這是與鎖定/併發模式有關,但我承認,我迷失了一個解決方案。

在客戶端我使用了通過添加服務引用生成的代理代碼。

服務器端應用程序。配置(僅相關份):

</configuration> 

客戶端側的App.config:

<configuration> 
<system.serviceModel> 
    <bindings> 
     <wsDualHttpBinding> 
      <binding name="WSDualHttpBinding_IPredatorEngine" closeTimeout="00:00:10" 
       openTimeout="00:00:10" receiveTimeout="00:10:00" sendTimeout="00:00:10" 
       bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" 
       messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"> 
       <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
        maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
       <reliableSession ordered="true" inactivityTimeout="00:10:00" /> 
       <security mode="Message"> 
        <message clientCredentialType="Windows" negotiateServiceCredential="true" 
         algorithmSuite="Default" /> 
       </security> 
      </binding> 
     </wsDualHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://localhost:8732/Design_Time_Addresses/MyApplication/MyApplication/" 
      binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IMyApplication" 
      contract="MyApplication.IMyApplication" name="WSDualHttpBinding_IMyApplication"> 
      <identity> 
       <dns value="localhost" /> 
      </identity> 
     </endpoint> 
    </client> 
</system.serviceModel> 
</configuration> 

我假設我沒有配置正確的東西。任何人都可以發現它?

回答

0

經過大量的搜索和反覆試驗,我發現我需要將SynchronizationContext設置爲false。

[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, UseSynchronizationContext=false)] 

我還需要設置客戶端代碼執行以下操作:

[CallbackBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, UseSynchronizationContext = false)]