1

In synchronous model it's simply

using (MyServiceClient msc = new MyServiceClient())
{
   msc.Method();
}

but if I must wait to end of this method, and then do something, it can't work

private void EventHandler<MethodCompletedEventArgs> myEventHandler = new EventHandler<MethodCompletedEventArgs>(methodBody);

using (MyServiceClient msc = new MyServiceClient())
{
   msc.MethdCompleted += myEventHandler;
   msc.BeginMethod();
}

private void MethodBody()
{
//exception: client state is aborted
}

Also how to call async mehod in using statement?

2
  • Which type of application is calling the service? Commented Oct 15, 2012 at 14:29
  • 4
    Call Dispose in your event handler Commented Oct 15, 2012 at 14:31

2 Answers 2

6

You should not do this.

You should instantiate MyServiceClient normally, then Dispose of it in the async callback handler.

This is the only way to ensure that the instance will still exist once the callback handler is called, and that it is destroyed after the callback handler has finished its work.

Sign up to request clarification or add additional context in comments.

Comments

1

You can store a reference to your service client and manually invoke its Dispose method once the event calls back. You just have to do some extra work managing exceptions and generally ensuring that Dispose is called eventually. Also watch for conditions where you might create/overwrite multiple instances of msc while waiting for an old one to complete:

One way to make sure that you don't dispose the wrong instance if you execute the same code multiple times is to use a local lambda/anonymous function:

MyServiceClient msc = new MyServiceClient();

msc.MethdCompleted += (sender, args) => 
{
    try
    {
        myEventHandler(sender, args);
    }
    finally
    {
        msc.Dispose();
    }
};

msc.BeginMethod();

It might get a bit messier than that; if an exception is thrown on msc.BeginMethod() you should catch that as well and call Dispose most likely (but you don't want to call Dispose more than once)

1 Comment

This isn't enough. The Dispose method calls Close(), which makes a call across the network to notify the other side to tear down the connection. If the connection is in Fault, Closing or Closed state then the Close() call will throw an exception and your resource will not be cleaned up. If that happens, you need to call Abort(). So it is not safe to simply use try/finally or using(){}...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.