none
VCSExpress debugger complains about unhandled exception, while it is indeed handled!

    Question

  • Hello. I have a very simple remoting client, and I want to handle the case where it does not find it's server :

     

    namespace Test
    {
        interface MyInterface
        {
            void Function();
        }

        class Program
        {
            static void Main(string[] args)
            {
                BinaryClientFormatterSinkProvider bcfFormatter = new BinaryClientFormatterSinkProvider();
                HttpClientChannel hccChannel = new HttpClientChannel(new Hashtable(), bcfFormatter);

                ChannelServices.RegisterChannel(hccChannel, false);

                MyInterface miRemoteObject=(MyInterface)Activator.GetObject(typeof(MyInterface), "http://noserver/MyInterface.rem");

                try
                {
                    miRemoteObject.Function();
                }
                catch (WebException ex)
                {
                    Console.WriteLine(ex.Message);
                }

                Console.Read();
            }
        }
    }

     

    If I run this, I catch a WebException telling me that the host "noserver" cannot be resolved. Which is right since I have no server. If I used a TcpClientChannel instead of Http, it would have been a SocketException telling me that the host is unknown, but it behaves the same.

     

    Good. It works. Now the problem. If I write a custom client channel sink, like all the samples you can see on the internet, the debugger thinks the WebException is no more caught... While it is still handled correctly (application does correctly catch the exception when run outside VS). I can't understand why...

    In this example I create a custom channel sink that does nothing.

     

    Here the sink:

     

    class MyCustomSink : BaseChannelSinkWithProperties, IClientChannelSink
        {
            #region IClientChannelSink Members

            public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
            {
                throw new Exception();
            }

            public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream)
            {
                throw new Exception();
            }

            public Stream GetRequestStream(IMessage msg, ITransportHeaders headers)
            {
                if (_ccsNextSink != null)
                {
                    return _ccsNextSink.GetRequestStream(msg, headers);
                }

                return null;
            }

            public IClientChannelSink NextChannelSink
            {
                get
                {
                    return _ccsNextSink;
                }
            }

            public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, out ITransportHeaders responseHeaders, out Stream responseStream)
            {

             // This line throws a WebException, and the debugger thinks it is not handled. But it is!
                _ccsNextSink.ProcessMessage(msg, requestHeaders, requestStream, out responseHeaders, out responseStream);


            }

            #endregion

            IClientChannelSink _ccsNextSink;

            public MyCustomSink(IClientChannelSink ccsNextSink)
            {
                _ccsNextSink = ccsNextSink;
            }
        }

     

     

    And here the provider :

     

    class MyCustomSinkProvider : IClientChannelSinkProvider
        {
            #region IClientChannelSinkProvider Members

            public IClientChannelSink CreateSink(IChannelSender channel, string url, object remoteChannelData)
            {
                IClientChannelSink ccsRet = null;
                if (_ccsNextSinkProvider != null)
                {
                    ccsRet = _ccsNextSinkProvider.CreateSink(channel, url, remoteChannelData);
                    if (ccsRet == null)
                    {
                        return null;
                    }
                }

                return new MyCustomSink(ccsRet);
            }

            public IClientChannelSinkProvider Next
            {
                get
                {
                    return _ccsNextSinkProvider;
                }
                set
                {
                    _ccsNextSinkProvider = value;
                }
            }

            #endregion

          IClientChannelSinkProvider _ccsNextSinkProvider;

            public MyCustomSinkProvider()
            {
            }
        }

     

     

    I insert these two lines in Main() before

    ChannelServices.RegisterChannel(hccChannel, false) :

     

    MyCustomSinkProvider mcsCustomSink = new MyCustomSinkProvider();

    bcfFormatter.Next = mcsCustomSink;

     

     

    If you try this, you will see that the debugger thinks the WebException (or SocketException if you use Tcp) is not caught anymore... But it is indeed!

     

    See this screen, shot when the debugger stops and tells me (wrong) that this line throws an unhandled WebException :

     

    You can download the solution at http://debaufree.free.fr/CustomClientSinkNoServer.zip

    Thursday, April 19, 2007 10:37 AM

Answers

  • It seems it is a "just my code option" bug...

    When I deactivate this option, the debugger does not complain anymore...

    Thursday, April 19, 2007 10:55 AM