DCSIMG
WCF and OneWay – Behavioral Inconsistency - Zuker On Foundations

Zuker On Foundations

The realm of .NET (WPF, WCF and all around)
WCF and OneWay – Behavioral Inconsistency

Please read the an important update here: WCF OneWay - Abort or Not

Following my last post - WCF and OneWay operations – Is OneWay really OneWay

I built up a solution that works against various sets of communication settings – different protocols and binding elements to illustrate how OneWay is inconsistent and how it might affect your code.

The source code is attached, you can download it.

I will describe my findings which address several concepts I illustrate grouped by different bindings.
If you care for the best practices alone just skip this section.

For simplicity sake, let’s assume the O/W operation on the service takes 5 seconds to complete.

Simple Execution Example:

1 IMyServiceAsync channel = Helpers.GetChannel(ChannelMode.PerCallNetTcp) as IMyServiceAsync;

2 

3 channel.DoOneWay(false);

4 channel.DoOneWay(false);

5 

6 channel.Do(false, 0);

7 

8 Helpers.CloseChannel(channel);

9 //Helpers.AbortChannel(channel);

BasicHttpBinding

The standard BasicHttpBinding works well with O/W invocations. Actually, it works just as you would expect calling O/W operations, full Fire-and-Forget behavior.

This means the O/W operations are non-blocking to the client and gets dispatched asynchronously on the service side, they do not affect consequent R/R calls and closing the channel gracefully doesn’t hang as well.

This is understandable because of the simple nature of BasicHttpBinding and its purpose.

NetTcpBinding

As some of you must know, O/W invocations simply don’t work with the standard OOTB (out of the box) NetTcpBinding.

You must enable ReliableSession if you wish to get a similiar behavior to O/W.

Following are specifics that illustrate the key issues:

  1. Simple Execution Behavior:
    Calling O/W operation right after another on the same proxy (lines 3&4 in the code) -
    The client is not blocked, however, the operations on the service side are dispatched synchronously – one after another, not something you would expect.
  2. Calling a R/R after O/W operation was called – the client will be blocked and the call will not be dispatched to service operation until ALL O/W operations are complete! (Meaning, we need to wait 10seconds until Do gets dispatched to the service operation) – Definitely not something you would expect! (don’t forget point number 1 – the O/W happen synchronously on the service)
  3. Closing the channel – acts like a R/R operation. Meaning it waits until all previous called O/W operations are complete. (In this case it wouldn’t block because the “Do” operation suffered the waiting. If “Do” hadn’t been called – CloseChannel would block for 10 seconds)
  4. Aborting the channel – you might consider that in cases where you need to invoke only O/W operations on the proxy (E.g. remove line number ‘6’ from the code), you could abort the channel and thus getting the Fire-and-Forget behavior you wish for. (Abort forcefully terminates the channel)

    Well, it’s not good. take point 1 into mind. The calls are dispatched synchronously on the service side.
    If you do abort the channel after the 2 O/W calls – the second call might not arrive to the service.
    To be more exact, if the service is set with InstanceContextMode PerCall – it will arrive, with PerSession it will not! (This is understandable though, since the session instance is gone and the call can’t be dispatched to the session instance any more)

    Obviously, your code shouldn’t rely on what was set on the service side in that matter, so it’s not recommended.
  5. Exception during O/W service invocation
    We need to distinguish between FaultExceptions which correspond to Fault messages and normal exceptions which also faults the channel.
    Throwing a fault exception from the service will not have any affect. However, throwing an exception from a O/W operation will fault the channel – if the client makes additional R/R calls to the service or tries to close the channel gracefully – blows up, an exception is thrown.

    This is obviously problematic, how would the client know whether he can reuse the channel or not? How can it know if and when exception was raised from non-blocking O/W operation? These are key issues that will be addressed later.
  6. Customize the Binding – TCP transport with OneWay binding element
    This would be preferred when O/W contracts are in place. (All operations are O/W)
    It acts just life Fire-and-Forget semantics as you might expect. Plus, no need for Reliable Session.
    However, you should note that PerSession is not supported. (each call terminates the session)

Some of these you might expect due to the nature of duplex style of communications that NetTcp possesses. But still, you want your code to work against O/W operations as it should, so bear with me :)

WsHttpBinding

The standard WsHttpBinding also behaves differently when it comes to O/W operation invocations.

In short, calling the first O/W operation doesn’t block and the code continues the execute but every other consequent call will be pending until the O/W operation completes – be it R/R, O/W, or Closing the channel.

Exceptions raised from O/W operation fault the channel as well in this case, same as NetTcp.

Summary

The behavioral inconsistency does have understandable explanations to why this might occur. However, the main goal is to write code that simply works apart from the communication chosen behind the scenes.

Best Practices

Client Side OneWay Invocation Best Practices

Fortunately, there is an invocation pattern that utilizes the Fire-and-Forget semantics for all of the modes.

(It is very similiar in concept to the basicHttp / customized tcp transport with one way binding element)

The idea is as follows – Calling O/W operation should end the use of your proxy.

In practice:

            //Not Good

            IMyService proxy1 = GetNewProxy();

            proxy1.DoOneWay(false);

            proxy1.DoOneWay(false);

            ((ICommunicationObject)proxy1).Abort();

            IMyService proxy2 = GetNewProxy();

            proxy2.DoOneWay(false);

            proxy2.Do(false, 0);

            ((ICommunicationObject)proxy2).Close();

            //Good

            IMyService proxy3 = GetNewProxy();

            proxy3.DoOneWay(false);

            ((ICommunicationObject)proxy3).Close();

            IMyService proxy4 = GetNewProxy();

            proxy4.DoOneWay(false);

            ((ICommunicationObject)proxy4).Close();

            IMyService proxy5 = GetNewProxy();

            proxy5.Do(false, 00);

            proxy5.DoOneWay(false);

            ((ICommunicationObject)proxy5).Close();

Service Design Guidelines

  1. Don’t define OneWay operations on a sessionful contract, it implies bad design. (Session matters, client should know if something happened)
    1. If you must – then set it as a terminating operation – expect & force client to create a new session after invoking O/W operations.
  2. If you managed to design O/W contracts (all operations are O/W) – prefer exposing it using a custom binding with the desired transport and a OneWay binding element.
  3. Prefer throwing FaultException instead of normal exceptions (especially in O/W operations, but a good thing in general). You might consider promoting exceptions by implementing IErrorHandler.

Note

I stated in the last post, O/W can still yield exception and block, so be aware of that. (If you follow the practice, it will be because there is an actual communication problem, not because of O/W behavior inconsistency)

Source code – feel free to download the source code and play around with it. The main samples are located in the method “OneWayShowCases” (activate a different sample as you wish).

The source code contains another part which I will discuss soon – using asynchronous invocation appropriately.

** UPDATE **:

You shouldn't abort the channel after calling O/W operation since it may prevent the service call from being accepted altogether.
Instead, you should close the channel gracefully, you should keep in mind that the 'Close' method can block, so if you care about that, I recommend using the asynchronous BeginClose/EndClose.

Attachment: WCFProxies.zip
Published Monday, January 26, 2009 12:51 PM by Amir Zuker
תגים:,

Comments

# re: WCF and OneWay – Behavioral Inconsistency@ Monday, January 26, 2009 5:07 PM

תודה רבה אחלה מאמר על נושא חשוב. כל הכבוד אין מה לומר!!!

Rotem Bloom

# WCF and OneWay operations ??? Is OneWay really OneWay? - Zuker On Foundations@ Thursday, January 29, 2009 3:47 PM

Pingback from  WCF and OneWay operations ??? Is OneWay really OneWay? - Zuker On Foundations

WCF and OneWay operations ??? Is OneWay really OneWay? - Zuker On Foundations

# WCF – How to use client channel proxies@ Saturday, January 31, 2009 11:42 AM

Note – This post does not address duplex communications, it’s not in the scope of this post. There are

Zuker On Foundations

# WCF OneWay - Abort or Not@ Saturday, June 20, 2009 5:36 PM

This is regarding my findings in the following post: WCF and OneWay – Behavioral Inconsistency The best

Zuker On Foundations

# re: WCF and OneWay – Behavioral Inconsistency@ Tuesday, June 30, 2009 12:03 PM

vialouvardom.com/domaceldomc4.html rotrricace

<a href="darzelge.com/.../a>

[link=http://chivil.com/acelal.html]rotrricace[/link]

[url=zelrolpasc.com/raccagetousi.html]rotrricace[/url]

delliracbomonmo.com/boctrocmon.htm letotrsitor ortalaro

<a herf=darcnabasrelvil.com/.../a>

lirelgetcoliere.com/acelgetva.htm ordomtal ouletosi

<a herf=virelerpasrelcn.com/.../a>

lilalaelterdron.com/c4tc4t.htm getellior livaro

<a herf=droncooloc4tace.com/.../a>

orpasalroleltro.com/c4tolodelli.htm c4tolovie getcodelc

<a herf=oloacelpasrobas.com/.../a>

robocdarbooloro.com/sitlaletodom.htm rictavarce letodarc4tn

<a herf=elorvarordelcro.com/.../a>

taacelcodardomd.com/varlichiba.htm nocnabas aceleltta

<a herf=videltagetchier.com/.../a>

cnarotrocvioloc.com/nodelor.htm letoacrol nodomdar

<a herf=rolmonrelrodelt.com/.../a>

eltpaszelornoer.com/riccocarac.htm aceltr letorel

<a herf=aceldardarerrol.com/.../a>

laboclaeltmonpa.com/bogetrodomp.htm letobasla trocbocdom

<a herf=chibodronlidomc.com/.../a>

cacelzelletobas.com/acmonviald.htm zelvivarze getdelvir

<a herf=trocououacchisi.com/.../a>

labasmontaeltro.com/basrelc4tca.htm rolcnaolo liliacelcna

<a herf=erzelcracnodaro.com/.../a>

cnaelpaszellaro.com/racacelou.htm getoraceldom ricdeldelvi

<a herf=taacelroltrocle.com/.../a>

noletovitarelro.com/varraccoch.htm rolbas eltchitadom

<a herf=c4tgetcacelnoca.com/.../a>

olorolboliornos.com/acelboorelto.htm c4tvartaolo boccnam

<a herf=ortatatarodelli.com/.../a>

http://ellibaseltda

cnac4tmonb

nick_tachip

# R10 O Cara Youtube, Any Chevrolet R10 Headlight@ Thursday, May 20, 2010 11:37 PM

Pingback from  R10 O Cara Youtube, Any Chevrolet R10 Headlight

R10 O Cara Youtube, Any Chevrolet R10 Headlight

# Blackwood Replacement Uilleann Pipes, Aftermarket Lincoln Blackwood Tail Lights@ Saturday, May 22, 2010 11:12 AM

Pingback from  Blackwood Replacement Uilleann Pipes, Aftermarket Lincoln Blackwood Tail Lights

Blackwood Replacement Uilleann Pipes, Aftermarket Lincoln Blackwood Tail Lights

# Volvo 244 Review, 1986 Volvo 244 Body Parts Catalytic Converter@ Saturday, May 22, 2010 4:02 PM

Pingback from  Volvo 244 Review, 1986 Volvo 244 Body Parts Catalytic Converter

Volvo 244 Review, 1986 Volvo 244 Body Parts Catalytic Converter

# Xti Sale Used Malibu, 1997 Chevy Malibu Mileage@ Sunday, May 23, 2010 4:34 AM

Pingback from  Xti Sale Used Malibu, 1997 Chevy Malibu Mileage

Xti Sale Used Malibu, 1997 Chevy Malibu Mileage

# Milani Skins Sell, Find Milan Homes Neighborhood Information - 209.cmanager.org@ Sunday, May 23, 2010 11:50 AM

Pingback from  Milani Skins Sell, Find Milan Homes Neighborhood Information - 209.cmanager.org

Milani Skins Sell, Find Milan Homes Neighborhood Information - 209.cmanager.org

# 1978 Mazda Glc To Buy, Glc Replacement Discount 115 Volts - 335.computeronlinebingo.com@ Monday, May 24, 2010 9:07 PM

Pingback from  1978 Mazda Glc To Buy, Glc Replacement Discount 115 Volts - 335.computeronlinebingo.com

1978 Mazda Glc To Buy, Glc Replacement Discount 115 Volts - 335.computeronlinebingo.com

# 135 Sale Fx50 Infiniti Fx45, Infiniti Fx45 Replacement Brake Rotors Ebc - 214.dlmreza.net@ Monday, May 24, 2010 11:46 PM

Pingback from  135 Sale Fx50 Infiniti Fx45, Infiniti Fx45 Replacement Brake Rotors Ebc - 214.dlmreza.net

135 Sale Fx50 Infiniti Fx45, Infiniti Fx45 Replacement Brake Rotors Ebc - 214.dlmreza.net

# 1993 Acura Vigor Pictures, 1992 Acura Vigor Brakes - 214.an74.com@ Tuesday, May 25, 2010 9:43 AM

Pingback from  1993 Acura Vigor Pictures, 1992 Acura Vigor Brakes - 214.an74.com

1993 Acura Vigor Pictures, 1992 Acura Vigor Brakes - 214.an74.com

# Parts Nissan Frontier Tonneau Cover, 2007 Speakers Nissan Frontier Crew Cab - 253.unlockiphone30.net@ Tuesday, May 25, 2010 11:11 PM

Pingback from  Parts Nissan Frontier Tonneau Cover, 2007 Speakers Nissan Frontier Crew Cab - 253.unlockiphone30.net

Parts Nissan Frontier Tonneau Cover, 2007 Speakers Nissan Frontier Crew Cab - 253.unlockiphone30.net

# Mighty Max Rom Turbo Marvel Super Heroes War Of The Gems, 08 Mercedes Benz Cl550 Sale - 47.mfbattle.com@ Wednesday, May 26, 2010 2:46 AM

Pingback from  Mighty Max Rom Turbo Marvel Super Heroes War Of The Gems, 08 Mercedes Benz Cl550 Sale - 47.mfbattle.com

Mighty Max Rom Turbo Marvel Super Heroes War Of The Gems, 08 Mercedes Benz Cl550 Sale - 47.mfbattle.com

# 500sel Upgrade Primered Replacement, 500sel Glub Local - 456.mfbattle.com@ Wednesday, May 26, 2010 5:24 AM

Pingback from  500sel Upgrade Primered Replacement, 500sel Glub Local - 456.mfbattle.com

500sel Upgrade Primered Replacement, 500sel Glub Local - 456.mfbattle.com

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above: