The other day I was asked “why should I use IsOneWay=true on my OperationContract? What does it actually do or optimize?”. In other words, what are the technical differences between:
[
OperationContract
]
void
Send(MyMessage message);
and:
[
OperationContract
(IsOneWay=
true
)]
void
Send(MyMessage message);
The first difference is semantics — even though you have a void
method, if you don’t mark the Operation with IsOneWay then we will wait for an ACK/NACK reply. There are a few other behavioral changes when you choose IsOneWay:
- The service will release the connection (or complete the HTTP request/response by replying with null, etc) before dispatching to user code. If the operation is not marked with IsOneWay then our Dispatcher won’t reply until the Operation has completed
- ServiceModel Runtime will ask for IOutputChannel first, before falling back to IRequestChannel or IDuplexSessionChannel if IOutputChannel isn’t available. This allows the underlying stack to make optimizations on send/receive.
- Service Model Faults will not be returned, so Exceptions caused by the Message-level processing are not propagated to the client (though it’s still possible to receive a framing-level fault such as an HTTP status code error).
In general, you should have your methods represent their semantic usages. This will help your overall design and allow the system to know best how to adapt to your intended usage. So if you are writing a true one-way notification (or building upon one-way methods for a duplex contract), be sure to remember the IsOneWay=
true
annotation.
Pingback: Sam Gentile : New and Notable 108
Pingback: Javier G. Lozano
Your 3rd point is the critical one – it’s not explicit in the documentation that WCF exceptions are swallowed by the stack and not propagated to the client, and this can lead to many hours of fruitless debugging trying to understand why my call succeeded while my target didn’t receive any message. I think it should be written loudly and clearly, possibly in horrid colors and blinking fonts, on the front page of the documentation. 🙂
I find it best to set IsOneWay to false during development, even if you plan to set it to True nearer the end of the project:
http://weblogs.asp.net/avnerk/archive/2006/05/16/446673.aspx
Pingback: WCF June/July CTP: QnA » Wagalulu - Microsoft » » WCF June/July CTP: QnA
Avner, I’m so upset! Just kidding. Above you mention that the docs don’t say this about exceptions/faults. They do! No really! But not, it must be admitted, in red. I’ll see if I can pull that off in the next release:
From http://windowssdk.msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.isoneway.aspx:
“Without waiting for an underlying response message, callers of one-way operations have no direct way to detect a failure in processing the request message. (Service applications that use stateful channels and one-way operations can detect a message delivery failure at the channel level. For details, see Reliable Sessions Overview.)”
And from Designing Service Contracts (http://windowssdk.msdn.microsoft.com/en-us/library/ms733070.aspx):
“No return message also means that there can be no SOAP fault returned to indicate any errors in processing or communication. (Communicating error information when operations are one-way operations requires a duplex message exchange pattern.)”
But I still take your point. I will make sure we get this information into your face right off. 🙂
Cheers, Ralph
Pingback: kennyw.com » Blog Archive » Asynchronicity, OneWay, and WCF
I have a question,
When a operation marked with IsOneWay=true, the client (web page) call:
myRemoteClass.DoTimeConsumeTasks();
myRemoteClass.Close() ==> What happen? The remote instance may be end? or killed by life cycle?
Thanks!
For one-way operations, Close is a flush, but often also a no-op. I’d need a lot more details about your scenario to be able to respond with more info
Pingback: New and Notable 108 : Sam Gentile's Blog