Update: Read the second post about the subject: WCF and OneWay – Behavioral Inconsistency
WCF has a simple and easy way to define operations that should be made as OneWay.
You do it by setting IsOneWay = true in the OperationContract attribute.
E.g.
[ServiceContract]
public interface IMyServiceOneWay
{
[OperationContract(IsOneWay = true)]
void DoOneWay(bool throwException);
}
The contract contains one operation – DoOneWay which will be invoked in a “OneWay” pattern (will be discussed later).
General things you should keep in mind about OneWay operations -
- O/W operations must return void.
- O/W operations can still yield exceptions. invoking an operation on the client channel might still throw an exception if it couldn’t transmit the call over to the service.
- O/W operations can still block. if the service is pumped with messages and a queue had started, calling O/W operation may block your following code.
Let’s look at the following execution code:
static void SimpleOneWayCalls()
{
IMyServiceOneWay oneWayChannel = Helpers.GetChannel(ChannelMode.PerCallHttp);
oneWayChannel.DoOneWay(false);
oneWayChannel.DoOneWay(false);
oneWayChannel.DoOneWay(false);
Helpers.CloseChannel(oneWayChannel);
}
The code illustrates a simple example of creating a channel, invoking 3 O/W operations and closing the channel.
From looking at the code along with the notion of the “O/W Fire-and-Forget” semantics, one would expect the following: (Assuming the service is free to receive calls and there are no communication exceptions while transmitting the call)
- The 3 calls “should” be done asynchronously
- They should not block
- They should be invoked asynchronously on the service
- Service operation exception in a single call should not affect other calls
- Calling a R/R (request-reply) operation on the same channel after calling these O/W operation should not be affected and should not be blocked until the O/W operation completes
- Same for closing the channel – should not be blocked until the O/W operation is completed on the service side.
So.. Is that the case?
Obviously and Unfortunately – Not! (Otherwise I wouldn’t be writing this post)
The state of the channel and the affect that O/W operations might have depend upon the communication settings between the client and the server.
Actually, it is dependent on various things, mainly the transport protocol and more regarding the channel shape and binding elements – reliable session / one way binding element. Moreover, it is even affected by the InstanceContextMode which is set on your service.
Ideally, we would wish that the behavior will be decoupled from all these things.
We wouldn’t want our logical code to suffer and implement plumbing to deal with all these various kinds of different behaviors. Unfortunately, this is not the case.
I am starting to build a new project that will expose client API library, One of its goals is to provide a level of abstraction to eliminate such differences, bringing it to a single phenomenon as we would expect and doing it right.
I plan to post more details and examples about OneWay different behaviors.
Furthermore, I will discuss best practices and design guidelines regarding these things.
CodeProject