1

I have an async service

The service contract defined like:

[ServiceBehavior(InstanceContextMode = InstanceContext.PerCall]
Myservice

My client is defined like:

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

task = new MyServiceClient(instanceContext);

task.MyMethod();

And the client class implements the call back methods (finish, progress etc...).

It's works fine, but if I call to the method, and she start running on the server and I shut down the server,I can't know the status of my call, and the client still think that the methods still running.

So, how can I check if this call is still running?

Thanks for helpers :)

Edit:

CallBack Interface:

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

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

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

}

Service Interface:

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

Service Class:

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

Client Class:

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

}

Edit: new client Class:

Client Class:

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

}
KfirZuberi
  • 51
  • 7

2 Answers2

0

In order to have more control of your clients request to the service, you should be able to use the inbuilt Task and Async support to monitor and if necessary handle connection delays.

The support for generating Task-based operations on the client side will be available to users who rely on proxies generated by our client generation tools (svcutil.exe or Add Service Reference), as well as to users who prefer to directly use ChannelFactory

The following code provides a rough example:

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

Refer to the following MSDN blog entry for more information: http://blogs.msdn.com/b/endpoint/archive/2010/11/13/simplified-asynchronous-programming-model-in-wcf-with-async-await.aspx

Regards,

Seymour
  • 7,043
  • 12
  • 44
  • 51
0

As @adkSerenity mention you may implement timeout logic, but I guess your question not about that.

The callback method will be(and should be) called in case of exception for example connection lose or internal connection time out.

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

      }
    }

So async communication looks like fire and forget. Your callback method will be called when you get the result(exception too), but if you decide not handle it(custom time out logic) you must "foret" about callback processing. No way to check is alive(except of course custom api).

sh1ng
  • 2,808
  • 4
  • 24
  • 38
  • My question is about: when I call to method on my service. And he stop working from some reason (like iisreset). The service don't throw exception.. So the client can't know that the method stop working... – KfirZuberi Nov 04 '13 at 14:41
  • Are you sure? Exception like "connection closed" must be thrown. Provide please more code. – sh1ng Nov 04 '13 at 14:46
  • Try to use IsOneWay=false – sh1ng Nov 05 '13 at 07:40
  • In the callbacks or in the service methods? – KfirZuberi Nov 05 '13 at 08:10
  • Both and add AsyncPattern=true.Use the IsOneWay property to indicate that an operation does not return a reply message. message http://msdn.microsoft.com/ru-ru/library/system.servicemodel.operationcontractattribute.isoneway%28v=vs.110%29.aspx – sh1ng Nov 05 '13 at 08:47
  • Still not working. Maybe I'll add callback method "alive" that will send to the client every 10 min... What do you think ? – KfirZuberi Nov 05 '13 at 12:31
  • How do you test this issue? – sh1ng Nov 05 '13 at 12:49