2013-11-09 77 views
1

我正試圖與WCF交手,特別是使用回調編寫WCF服務應用程序。回調中的WCF服務超時

我已經設置了服務和回調協議,但是當回調被調用時,應用程序超時。

本質上,從客戶端我設置服務類內的屬性。這個屬性的Setter,如果驗證失敗會觸發回調,並且,這是超時。

我意識到這可能是它不是一個異步的回調,但有人可以告訴我如何解決這個問題?

感謝

// The call back (client-side) interface 
public interface ISAPUploadServiceReply 
{ 
    [OperationContract(IsOneWay = true)] 
    void Reply(int stateCode); 
} 

// The Upload Service interface 
[ServiceContract(CallbackContract = typeof(ISAPUploadServiceReply))] 
public interface ISAPUploadService 
{ 

    int ServerState 
    { 
     [OperationContract] 
     get; 
     [OperationContract(IsOneWay=true)] 
     set; 

和實現...

public int ServerState 
    { 
     get 
     { 
      return serverState; 
     } 
     set 
     { 
      if (InvalidState(Value)) 
      { 
       var to = OperationContext.Current.GetCallbackChannel<ISAPUploadServiceReply>(); 
       to.Reply(eInvalidState); 
      } 
      else serverState = value; 
     } 
    } 

我的接口已被修改(希望)反映了異步能力

// The call back (client-side) interface 
public interface ISAPUploadServiceReply 
{ 
    [OperationContractAttribute(AsyncPattern = true)] 
    IAsyncResult BeginReply(string message, AsyncCallback callback, object state); 
    void EndReply(IAsyncResult result); 
} 

..和實施(請,我非常,非常猜測 - 除此之外它不起作用 - 「服務器回答了run未知的響應時間的錯誤......」

public class SAPUploadServiceClient : ISAPUploadServiceReply 
{ 
    private string msg; 

    public IAsyncResult BeginReply(string message, AsyncCallback callback, object state) 
    { 
     // Create a task to do the work 
     msg = message; 
     var task = Task<int>.Factory.StartNew(this.DisplayMessage, state); 
     return task.ContinueWith(res => callback(task)); 

    } 

    public void EndReply(IAsyncResult result) 
    { 
     MessageBox.Show(String.Format("EndReply")); 
    } 

    private int DisplayMessage(object state) 
    { 
     MessageBox.Show(String.Format("Display Message At last here's the message : {0}", msg)); 
     return 1; 
    } 
} 

回調是通過一個公共的方法我的服務中被調用時,從客戶端

public void FireCallback(string msg) 
    { 
     ISAPUploadServiceReply callback = OperationContext.Current.GetCallbackChannel<ISAPUploadServiceReply>(); 

     callback.BeginReply("Hello from service " + msg, callback.EndReply, null); 
    } 

的界面修改是可調用...

[ServiceContract(CallbackContract = typeof(ISAPUploadServiceReply))] 
public interface ISAPUploadService 
{ 
    [OperationContract(IsOneWay = true)] 
    void FireCallback(string msg); 

請 - 我知道上面看起來相當絕望,這就是它的原因。我只是想從我的WCF服務中獲得任何回撥,所以我可以繼續使用它。簡單地調用異步回調不應該很難。

我只想從服務中向客戶端發送事件。這就是我想要做的。下面可能解釋了我試圖更清楚地實現的事件的過程...

客戶端調用服務方法並等待... 服務方法1承擔一些工作(在這種情況下,查詢數據庫和構建一個xml響應) 工作完成後,該服務會觸發一個回調事件,通知客戶工作已完成,並且XML響應可用。 客戶端讀取XML響應並繼續。

嘖......

回答

2

我不是100%肯定,但我記得我有這樣的問題時,我打電話從同一個線程回調方法.. 這應該解決這個問題:

public int ServerState 
    { 
     get 
     { 
      return serverState; 
     } 
     set 
     { 
      if (InvalidState(Value)) 
      { 
       var to = OperationContext.Current.GetCallbackChannel<ISAPUploadServiceReply>(); 
       Task.Factory.StartNew(() => 
        { 
         to.Reply(eInvalidState); 
        }); 

      } 
      else 
       serverState = value; 
     } 
    } 
+1

AJ,太感謝很多回復。但我對你的解決方案和我讀過的異步回調之間的區別感到困惑。絕對令人憤慨的是,我可以找到一個關於如何定義異步回調的例子,但沒有NONE,絕對沒有關於如何從服務調用smegging回調的例子。所有示例都顯示瞭如何定義回調接口,但沒有顯示如何實際使用IT。引用Basil Fawlty - '什麼是bl ** dy點..' –

3

服務器端:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class Service1 : IService1 { ... } 

執行回調(服務):

var to = OperationContext.Current.GetCallbackChannel<IChatServiceCallback>(); 
Task.Factory.StartNew(() => 
{ 
    to.myCallbackFunction(...); 
}); 

客戶端回調:

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)] 
public class MyServiceCallback : IService1Callback { ... }