The effect of IsOneWay on Operations

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:

  1. 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
  2. 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.
  3. 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.

8 Responses to “The effect of IsOneWay on Operations”

  1. Sam Gentile : New and Notable 108 Says:

    […] of OneWay on Operations   Share this post: Email it! | bookmark it! | digg it! | reddit!| kick it! Published Friday, July 07, 2006 8:00 AM by SamGentile Filed Under: Data, LINQ and OR/M, Newand Notable, WCF/Indigo […]

  2. Javier G. Lozano Says:

    IsOneWay Property for WCF Operations…

  3. Avner Kashtan Says:

    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

  4. WCF June/July CTP: QnA » Wagalulu - Microsoft » » WCF June/July CTP: QnA Says:

    […] practices for TFS Proxy » Bookmark on del.icio.us We have an internal alias where people developing apps on WCF post questions. Generally we see somequestions that are commonly faced by people and thought it would be a good idea to make a quick HowTo or QnA on some topics that WCF newbie users may find useful. Q: How to know if a server channel is sessionful or not? A: Couple of ways.        OperationContext.Current.SessionId != null or    OperationContext.Current.Channel.SessionId != null Q: WCF service runtime disposes off all input/output parameters once the operation is invoked. How can I cache the input arguments? A: Mark you operation implementation with OperationBehavior with AutoDisposeParameters set to false.    [OperationBehavior(AutoDisposeParameters=false)]    public void Foo(Message m, FooDisposableObj f)    {       //Implementation    } Q: Why is OperationContext.Current.RequestContext null? A: Because the operation is OneWay. RequestContext is not null only for request/reply.   Q: Why does the first call on a newly created channel take longer to complete than subsequent calls? A: Its possible that the delay is due to AutoOpen feature. If a channel is not in Opened state when a call is made then the channel is “auto opened” for the user. Users can explicitly open a channel by doing ((IClientChannel)channel).Open(); or proxy.Open() ==> If proxy is of type ClientBase   Q: If a binding does not use ReliableMessaging, then is the order preserved for all async calls made on a Channel using that binding? A: Yes. Q: What’s the difference between ConcurrencyMode.Single and ConcurrencyMode.Reentrant. They seem to process only one message at any time? A: Reentrant is actually analogus to ConcurrencyMode.Single in that it will process only one message at a given time. The only difference is that the service is unblocked to process a new message when the user makes an outgoing call while processing a message. Q: If I have multiple messages/channels waiting for a throttle (Call/Session/InstanceContext), how fair is WCF to the waiters? A: First come first serve. Q: Whats the implications of using IsOneWay=true on an OperationContract? A: KennyW has a wonderful post on this at http://kennyw.com/indigo/130 Q: How do I know if the throttle limit set on the ServiceHost is too restrictive? A: Well thats a decision the customer needs to make based on the load they expect. But in test environment, enable logging and if there is too many occurances of “The system hit the limit set for the ‘[One of the throttles]’ throttle. Throttle value can be changed by modifying…” then it probably means that that particular throttle is too restrictive. Thats all the time I have today for this list. There is lot more that I will try to post by the end of the week. Maheshwar Jayaraman [WCF] […]

  5. Ralph Says:

    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

  6. kennyw.com » Blog Archive » Asynchronicity, OneWay, and WCF Says:

    […] recently encountered some confusion around the behavior of one-way operations in WCF that I’m going to try and clear up.  In particular, developers are under the impression […]

  7. Ngan Pham Says:

    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!

  8. Kenny Says:

    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

Leave a Reply