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();
    }

}
4

2 回答 2

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

      }
    }

所以异步通信看起来就像一发不可收拾。您的回调方法将在您获得结果时被调用(也有异常),但如果您决定不处理它(自定义超时逻辑),您必须“忘记”回调处理。没有办法检查是否还活着(当然自定义 api 除外)。

于 2013-11-04T13:24:10.917 回答
0

为了更好地控制客户对服务的请求,您应该能够使用内置的任务和异步支持来监控并在必要时处理连接延迟。

依赖于我们的客户端生成工具(svcutil.exe 或添加服务参考)生成的代理的用户,以及喜欢直接使用 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

问候,

于 2013-11-04T11:41:53.420 回答