Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Callback Interface - Who closes the channel

Tags:

wcf

I have problems/questions closing a callback/duplex communication channel. Here are my prototypical WCF interfaces:

[ServiceContract(CallbackContract = typeof(IMyInterfaceCallback))]
public interface IMyInterface
{
    [OperationContract]
    void StartWork();
}

public interface IMyInterfaceCallback
{
    [OperationContract(IsOneWay = true)]
    void WorkFeedback();
}

On the client side I create my WCF interface via:

DuplexChannelFactory<IMyInterface> dcf = new DuplexChannelFactory<IMyInterface>(implOfIMyInterfaceCallback, customBinding, ea);
IMyInterface myInterface = dcf.CreateChannel();

On the server side I then use

OperationContext.Current.GetCallbackChannel<IMyInterfaceCallback>();

to retrieve the callback pointer, which can then be used to communicate with the client.

My questions now are:

  1. Who should close the communication channel? The client or the server
  2. Which communication objects need to be closed? The original interface (IMyInterface) or the callback interface (IMyInterfaceCallback) or both.

I tried to close the callback interface on the server side, at the time when the server knows it will do no more callbacks. Using the ICommunicationObject::Close on the callback interface however resulted in a one-minute blocking operation.

Closing on the client side in my opinion is not the right way, as the client does not know if there are more callbacks to be expected.

Thanks for any help. Frank

P.S.: This seems to be a very basic question, but so far I found no helpful information when searching via google or in stackoverflow...

like image 653
FrankE Avatar asked Dec 13 '11 16:12

FrankE


1 Answers

The client should close the service channel (as normal).

The callback channel acquired through GetCallbackChannel should NOT be closed in my experience (See this related question of mine: Do I need to Close and/or Dispose callback channels acquired through OperationContext.Current.GetCallbackChannel?)

When closing the channel you should use the preferred pattern:

Try
    channel.Close()
Catch ex As Exception
    channel.Abort()
End Try

Because the client (usually) can not know whether or not any messages are still being underway while attempting to close the channel, which would result in an exception.

like image 114
Peladao Avatar answered Sep 21 '22 00:09

Peladao