2013-11-04 80 views
1

我有一個異步服務定義如下檢查一個異步調用的服務還活着

服務合同:

[ServiceBehavior(InstanceContextMode = InstanceContext.PerCall] 
Myservice 

我的客戶的定義如下:

MyServiceClient task= null; 
InstanceContext instanceContext = new InstanceContext(this); 

task = new MyServiceClient(instanceContext); 

task.MyMethod(); 

而客戶端類實現回調方法(完成,進度等)。

它的工作正常,但如果我調用該方法,並且她開始在服務器上運行並關閉服務器,我無法知道我的調用狀態,並且客戶端仍然認爲方法仍然存在運行。

那麼,如何檢查此通話是否仍在運行?

感謝傭工:)

編輯:

回調接口:

public interface IServiceCallback 
{ 
    [OperationContract(IsOneWay=true)] 
    void NotifyFinished(); 

    [OperationContract(IsOneWay=true)] 
    void NotifyProgress(int x); 

    [OperationContract(IsOneWay=true)] 
    void NotifyFailed(Exception exception); 

} 

服務接口:

[ServiceContract(CallbackContract = typeof (IServiceCallback)] 
public interface IAsyncService 
{ 
    [OperationContract(IsOneWay=true)] 
    void AsyncRunning(); 
} 

服務類:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 
public class AsyncService : IAsyncService 
{ 
    private IServiceCallback ServiceCallback {get; set;} 

    public void AsyncRunningProxy() 
    { 
     for(int x=0; x<100 ; x++) 
     { 
      AsyncService.NotifyProgress(x); 
     } 
    } 

    private void EndMethod(IAsyncResult res) 
    { 
     AsyncResult result = (AsyncResult)res; 
     try 
     { 
      ((dynamic)result.AsyncDelegate).EndInvoke(res); 
      AsyncService.NotifyFinished(); 
     } 
     catch (Exception e) 
     { 
      AsyncService.NotifyFailed(e); 
     } 

    } 

    public void AsyncRunning() 
    { 
     ServiceCallback = OperationContext.Current.GetCallBackChannel<IServiceCallback>(); 
     Action action = AsyncRunningProxy; 

     action.BeginInvoke(EndMethod, null); 
    } 
} 

客戶端類:

public class ServiceRunner : IServiceCallback 
{ 
    private ManualResetEvent reset {get; set;} 

    public ServiceRunner() 
    { 
     reset = new ManualResetEvent(false); 
    } 

    public void Run() 
    { 
     AsyncServiceClient client = null; 

     InstanceContext instanceContext = new InstanceContext(this); 

     client = new AsyncServiceClient(instanceContext); 

     client.AsyncRunning(); 

     reset.WaitOne(); 
    } 

    public void NotifyProgress(int x) 
    { 
     Console.WriteLine(x); 
    } 

    public void NotifyFinished() 
    { 

    } 

    public void NotifyFailed(Exception e) 
    { 
     Console.WriteLine(e.Message); 
     reset.Set(); 
    } 

} 

編輯:新的客戶端類:

客戶端類:

public class ServiceRunner : IServiceCallback 
{ 
    private ManualResetEvent reset { get; set; } 

    private string IsRunning { get; set; } 

    public ServiceRunner() 
    { 
     reset = new ManualResetEvent(false); 
     IsRunning = true; 
    } 

    public void Run() 
    { 
     AsyncServiceClient client = null; 

     InstanceContext instanceContext = new InstanceContext(this); 

     client = new AsyncServiceClient(instanceContext); 

     client.AsyncRunning(); 

     new Thread(()=> 
     { 
      while(IsRunning) 
      { 
       try 
       { 
        client.IsAlive(); 
        Thrad.Sleep(60 * 1000); 
       } 
       catch (Exception e) // The server is not responding. 
       { 
        NotifyFailed(e); 
        return; 
       } 
      } 
     }).Start(); 

     reset.WaitOne(); 
    } 

    public void NotifyProgress(int x) 
    { 
     Console.WriteLine(x); 
    } 

    public void NotifyFinished() 
    { 
     IsRunning = false; 
     reset.Set(); 
    } 

    public void NotifyFailed(Exception e) 
    { 
     IsRunning = false; 
     Console.WriteLine(e.Message); 
     reset.Set(); 
    } 

} 

回答

0

爲了讓客戶有更多的控制要求的服務,你應該能夠使用內置的任務和異步支持來監視和必要時處理連接延遲。

對依賴客戶端生成工具(svcutil.exe或Add Service Reference)生成的代理的用戶以及喜歡直接訪問客戶端的用戶可以使用對客戶端生成基於任務的操作的支持使用的ChannelFactory

下面的代碼提供了一個粗略的例子:

Task<string> task = new MyServiceClient().MyMethod(); 
if (task == await Task.WhenAny(task, Task.Delay(1000))) 
{ 
    Console.WriteLine(await task); 
} 
else 
{ 
    // handle delay … 
} 

請參閱下面的MSDN博客文章以瞭解更多信息: http://blogs.msdn.com/b/endpoint/archive/2010/11/13/simplified-asynchronous-programming-model-in-wcf-with-async-await.aspx

Regards,

0

作爲@adkSerenity提到你可能實現超時邏輯,但我想你的問題不是關於這一點。

回調方法將被(並應該)在例外情況下調用,例如連接丟失或內部連接超時。

private static void CallbackSample(IAsyncResult asynchronousResult) 
    { 
     try 
     { 
     // State of request is asynchronous. 
     RequestState myRequestState=(RequestState) asynchronousResult.AsyncState; 
     HttpWebRequest myHttpWebRequest2=myRequestState.request; 
     myRequestState.response = (HttpWebResponse); 
//next line may throw exception 
myHttpWebRequest2.EndGetResponse(asynchronousResult); 

     } 
     catch(WebException e) 
     { 

     } 
    } 

所以異步通信的樣子射後不理。當你得到結果(例外)時,你的回調方法會被調用,但如果你決定不處理它(定製超時邏輯),你必須回調處理的「foret」。沒有辦法檢查活着(當然除了自定義API)。

+0

我的問題是:當我打電話給我的服務方法。他因某種原因停止工作(如iisreset)。該服務不會拋出異常..所以客戶端不能知道該方法停止工作... – KfirZuberi

+0

你確定嗎?例如「連接關閉」必須被拋出。請提供更多代碼。 – sh1ng

+0

嘗試使用IsOneWay = false – sh1ng