Zhou's profileSheva's TechSpacePhotosBlogLists Tools Help

Blog


    11/10/2007

    WCF Trip - What Happens To BeginInvoke

        Recently I came across Nicholas Allen's blog post talking about how BeginInvoke breaks when used against proxies generated by WCF client runtime, specifically the ChannelFactory. and his conclusion to the misbehaviour exposed by BeginInvoke right here is something like this (quoted from the original article):

    The problem is that BeginInvoke knows about and only works with specific types of proxy objects, which do not include the proxy objects generated by ChannelFactory.

        Actually Nicholas Allen's reasoning here is kinda like a "technical correct but lack of detailed explanation" statement, if you write something like the following, no one can imagine that you are actually doing something wrong:

    String uri = "net.tcp://localhost:2222/Services";
    ChannelFactory<IEchoService> factory = new ChannelFactory<IEchoService>(new NetTcpBinding(), uri);
    IEchoService proxy = factory.CreateChannel();
    EchoDelegate d = new EchoDelegate(proxy.Echo);
    IAsyncResult result = d.BeginInvoke("foo", new AsyncCallback(Callback), null);

       So what really happens here?

       Let's first add some piece of code into the original testing code to check some of presumptions I make on the proxy generated by ChannelFactory:

    Console.WriteLine(System.Runtime.Remoting.RemotingServices.IsTransparentProxy(proxy));
    Console.WriteLine(System.Runtime.Remoting.RemotingServices.GetRealProxy(proxy).GetType());
    Console.WriteLine(result.IsCompleted);

       If running the modified code, you will find some of the interesting bits:

    1. The proxy generated by WCF client runtime aka ChannelFactory is actually a TransparentProxy;
    2. The RealProxy paired with this TransparentProxy is a System.ServiceModel.Channels.ServiceChannelProxy implementation;
    3. When beginInvoking against a proxy generated by ChannelFactory, the call is performed as ordinary synchronous method invocation.

       So what's the happening here? How does WCF relate to the remoting architecture such as TransparentProxy and RealProxy metaphors? and specifically why does BeginInvoke break here?

       To answer those questions, let's first take on the first question, and digg into it, I've spent several hours to examine the implementation of WCF ChannelFactory implementation, one of the greatest discovery I find is that before kicking off the channel stack to process the service request, WCF client runtime will actually intercept every WCF service call by injecting a TransparentProxy and ServiceChannelProxy between WCF service call site and underlying the channel stack. The reason WCF implements the client runtime the way it is is that WCF needs to differ between normal method invocation and WCF service invocation on service proxy objects. how about if you call GetType() on the proxy generated by the ChannelFactory, what type do you expect the GetType() method will return? If you write the code to test, you will get stunned by realizing that GetType() will actually return IEchoService, WTF? How does GetType() method return the interface type object rather than the concrete type object? Actually, WCF has been intercepted the call to GetType(), and revamped it to return the underlying proxied type, thus hiding the real proxy implementation for IEchoService. Another reason WCF intercepts every method call is to differ between synchronous service calls and asynchronous service calls. Imagine you have a WCF service contract like this:

    [ServiceContract]
    public interface IEchoService
    {
        [OperationContract]
        String Echo(String text);
    }

       If you run the svcutil.exe tool to generate client side proxy implementation for async call just as Nicholas Allen suggested in his original article:

       svcutil /language:C# /config:App.config /async net.tcp://localhost:2222/Services

       you will get something like this:

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    [System.ServiceModel.ServiceContractAttribute(ConfigurationName="IEchoService")]
    public interface IEchoService
    {
       
        [System.ServiceModel.OperationContract]
        string Echo(string text);
       
        [System.ServiceModel.OperationContract]
        System.IAsyncResult BeginEcho(string text, System.AsyncCallback callback, object asyncState);
       
        string EndEcho(System.IAsyncResult result);
    }

    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    public interface IEchoServiceChannel : IEchoService, System.ServiceModel.IClientChannel
    {
    }

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
    public partial class EchoServiceClient : System.ServiceModel.ClientBase<IEchoService>, IEchoService
    {
       
        public EchoServiceClient()
        {
        }
       
        public EchoServiceClient(string endpointConfigurationName) : base(endpointConfigurationName)
        {
        }
       
        public EchoServiceClient(string endpointConfigurationName, string remoteAddress) :
                base(endpointConfigurationName, remoteAddress)
        {
        }
       
        public EchoServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress)
        {
        }
       
        public EchoServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress    remoteAddress) : base(binding, remoteAddress)
        {
        }
       
        public string Echo(string text)
        {
            return base.Channel.Echo(text);
        }
       
        public System.IAsyncResult BeginEcho(string text, System.AsyncCallback callback, object asyncState)
        {
            return base.Channel.BeginEcho(text, callback, asyncState);
        }
       
        public string EndEcho(System.IAsyncResult result)
        {
            return base.Channel.EndEcho(result);
        }
    }

        From the above code, we find that WCF follows .NET's asynchronous method invocation pattern quite closely by pairing each service operation call XX with a BeginXX and EndXX async call implementation. the code shown above is really clear and standard, but how does it work out actually? How does a BeginXX call will be performed asynchronously? and how does a EndXX kicks in here to finalize the asynchronous service invocation?

       In order to let the BeginXX and EndXX work as their signature indicate, WCF actually needs to know which service invocation is going to be performed through BeginXX or EndXX calls, to put it another way, WCF needs to know if the BeginXX or EndXX has been called, so it will perform its underlying plumbing to do the magic, in order to get those invocation infomation, WCF needs to have the capability to fine-grained control over the invocation of the service operations exposed by the service contracts. Since TransparentProxy and RealProxy mechanism which is heavily used by the .NET remoting has already haven this capability directly built into the CLR, WCF can leverage this infrastructure to intercept the method calls, and perform its underlying async plumbing at the channel level according to method you are going to invoke.

       Right now, I am almost finishing answering the first question - How does WCF relate to the remoting architecture such as TransparentProxy and RealProxy metaphors? but how about the second question I raised myself, why does BeginInvoke break when all the TP and RP plumbing is in place? This question is much trickier than it seems to be, after a bit of research on the default implementation of TP and RP mechanism used by .NET remoting using both  .NET reflector and the rotor 2.0 implementation of CLR, I finally figure out that for the current implementation of TP and RP mechanism, it only supports asynchronous call when the default RemotingProxy is in place, since the ServiceChannelProxy is WCF's own implementation, it gets ignored by the BeginInvoke mechanism, and the BeginInvoke call against WCF's proxies will be performed synchronously.

       Up until now, all the puzzles has been demystified. BeginInvoke is probably one of the most confusing APIs in the .NET framework as this article and my previous article demonstrates:)

    Comments (14)

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.
    Zhou Yong has turned off comments on this page.
    No namewrote:
    Pele had been asked, are you <a href="http://www.uggbootsdirect.com" title="ugg boots">ugg boots</a> the most beautiful goal which, he laughingly <a href="http://www.uggbootsdirect.com/" title="uggs">uggs</a> said, the next.
    Sculptor Rodin also <a href="http://www.ismachines.com" title="High pressure blower">High pressure blower</a> use their own Graver told the world that he is satisfied with the <a href="http://www.ismachines.com" title="Industrial fan">Industrial fan</a> sculpture is an under.
    These outstanding <a href="http://www.ismachines.com" title="Industrial blower">Industrial blower</a> people left in the world one of the major <a href="http://www.ismachines.com" title="Commercial blower">Commercial blower</a> scientific research results, one after another <a href="http://www.downtownkey.com/" title="wholesale">wholesale</a> exciting moment, one of the artistic peak. Yes, because <a href="http://www.downtownkey.com/" title="china wholesale">china wholesale</a> they do not get complacent and honor, pride complacent, they do not have the reputation as a tired, because they <a href="http://www.downtownkey.com/jewelry-wholesale-18" title="wholesale jewelry">wholesale jewelry</a> do not have been lost over the success of the self-drive, after the <a href="http://www.downtownkey.com/computers-wholesale-12" title="wholesale computers">wholesale computers</a> success they always look forward to the next beautiful.
    Regular life <a href="http://www.downtownkey.com/christmas-supplies-wholesale-15_139" title="wholesale christmas supplies">wholesale christmas supplies</a> is full of expectation, that in itself <a href="http://www.downtownkey.com/cell-phones-wholesale-10" title="Wholesale Cell Phones">Wholesale Cell Phones</a> is a kind of beautiful.
    Look forward to the <a href="http://www.downtownkey.com/handbags-wholesale-11_701" title="wholesale handbags">wholesale handbags</a> next beautiful, perhaps we will have <a href="http://www.downtownkey.com/mp3-and-accessories-wholesale-13_98" title="wholesale MP3">wholesale MP3</a> to dilute some of the existing successful <a href="http://www.downtownkey.com/mp4-and-accessories-wholesale-13_950" title="wholesale MP4">wholesale MP4</a> joy, and look forward to is not the same wait, we also <a href="http://www.downtownkey.com/mp5-and-accessories-wholesale-13_951" title="wholesale MP5">wholesale MP5</a> look forward to keep working hard to pay, but <a href="http://www.ismachines.com" title="pressure blower">pressure blower</a> our life will be full of passion and fighting spirit.
    Life in a big ideals, which <a href="http://www.ismachines.com" title="pressure blowers">pressure blowers</a> constitute the ideal stage of the numerous, successful <a href="http://www.ismachines.com" title="fans">fans</a> life by numerous constitute a successful stage. In the face of success, "not-to-hi," Do <a href="http://www.ismachines.com" title="blowers">blowers</a> not stop the pace, we <a href="http://www.downtownkey.com/ugg-boots-wholesale-11_962" title="ugg boots">ugg boots</a> measure both feet on the lives of more broad.
    Dec. 15
    Nov. 27
    Nov. 20
    No namewrote:
    労働問題 収益物件不動産売却などにはマンション査定土地売買1戸建て売却が含まれる賃貸 住宅不動産 賃貸賃貸マンション新築マンションもしっかりカバーしてありすごく充実したさいとでもちろん投資を目的の方やリフォームをしたい人もすごく参考になるだう。ところで今,SEO対策などいまはやっているがホームページ制作会社にいらいしてもうまくはいかないようだ。最近私は、資産運用にこっていて税金対策にインテリアを集めている。もちろんファッションにこだわりブランド品や下着,ランジェリーにはこだわりがある。 化粧品ダイエット用品高価なものがよく家具も最高級しか買わない、先日海外旅行にいってきてお土産に外車結婚指輪と高級時計をかったが、日本でしらべたら通販ですごく安く売っていた。 物件探しは広島 不動産 岡山 不動産 松山市 不動産 香川県 不動産 徳島 不動産 高知 不動産 高松 不動産をフルカバーしてます大手で 和歌山 富山 滋賀 石川 山梨 新潟 沖縄 大分 鹿児島 宮崎 熊本 高知
    Nov. 20
    Nov. 8
    Nov. 8
    Oct. 21
    No namewrote:
    HTML clipboard情趣用品,情趣用品,情趣用品,情趣用品,情趣,情趣,情趣,情趣,按摩棒,震動按摩棒,微調按摩棒,情趣按摩棒,逼真按摩棒,G點,跳蛋,跳蛋,跳蛋,性感內衣,飛機杯,充氣娃娃,情趣娃娃,角色扮演,性感睡衣,SM,潤滑液,威而柔,香水,精油,芳香精油,自慰套,自慰,性感吊帶襪,吊帶襪,情趣用品加盟AIO交友愛情館,情人歡愉用品,美女視訊,情色交友,視訊交友,辣妹視訊,美女交友,嘟嘟成人網,成人網站,A片,A片下載,免費A片,免費A片下載情人歡愉用品,情趣用品,成人網站,情人節禮物,情人節,AIO交友愛情館,情色,情色貼圖,情色文學,情色交友,色情聊天室,色情小說,七夕情人節,色情,情色電影,色情網站,辣妹視訊,視訊聊天室,情色視訊,免費視訊聊天,美女視訊,視訊美女,美女交友,美女,情色交友,成人交友,自拍,本土自拍,情人視訊網,視訊交友90739,生日禮物,情色論壇,正妹牆,免費A片下載,AV女優,成人影片,色情A片,成人論壇,情趣,情境坊歡愉用品,免費成人影片,成人電影,成人影城,愛情公寓,成人影片,保險套,舊情人,微風成人,成人,成人遊戲,成人光碟,色情遊戲,跳蛋,按摩棒,一夜情,男同志聊天室,肛交,口交,性交,援交,免費視訊交友,視訊交友,一葉情貼圖片區,性愛,視訊,視訊聊天,A片,A片下載,免費A片,嘟嘟成人網,寄情築園小遊戲,女同志聊天室,免費視訊聊天室,一夜情聊天室,聊天室愛情公寓,情色,舊情人,情色貼圖,情色文學,情色交友,色情聊天室,色情小說,一葉情貼圖片區,情色小說,色情,色情遊戲,情色視訊,情色電影,aio交友愛情館,色情a片,一夜情,辣妹視訊,視訊聊天室,免費視訊聊天,免費視訊,視訊,視訊美女,美女視訊,視訊交友,視訊聊天,免費視訊聊天室,情人視訊網,影音視訊聊天室,視訊交友90739,成人影片,成人交友,美女交友,微風成人,嘟嘟成人網,成人貼圖,成人電影,A片,豆豆聊天室,聊天室,UT聊天室,尋夢園聊天室,男同志聊天室,UT男同志聊天室,聊天室尋夢園,080聊天室,080苗栗人聊天室,6K聊天室,女同志聊天室,小高聊天室,上班族聊天室,080中部人聊天室,同志聊天室,聊天室交友,中部人聊天室,成人聊天室,一夜情聊天室,情色聊天室,寄情築園小遊戲
    Oct. 14
    Sept. 30
    Sept. 6
    Sept. 6
    Sept. 6
    Sept. 6
    July 24

    Trackbacks

    The trackback URL for this entry is:
    http://shevaspace.spaces.live.com/blog/cns!FD9A0F1F8DD06954!588.trak
    Weblogs that reference this entry
    • None