none
WCF SendTimeout, ReliableSession and Async Operation RRS feed

  • Question

  • I am bit confused with reliable session in WCF. I have a client application which enable reliable session, i config SendTimeout = TimeSpan.FromSeconds(5)  (5 seconds), i call a long-running service operation (greater than 5s). If the long-running operation is run synchronously an exception will be thrown after 5s, but if it run asynchronously timeout error will not be thrown and the client will wait until it is completed. 

    How to catch error in asynchronous scenario ?

    The test program code is:

    var _bd = new WSHttpBinding();
    _bd.Security.Mode = SecurityMode.None;
    _bd.ReliableSession.Enabled = true;
    _bd.SendTimeout = TimeSpan.FromSeconds(5);
    
    var _factory = new ChannelFactory<IService1>(_bd, "http://localhost:61228/IService1.svc");
    var _conn = _factory.CreateChannel();
    var _icc = _conn as IContextChannel;
    
    try
    {
       _icc.Open();
       await _conn.longRunning();
       MessageBox.Show("Completed");
    }
    catch
    {
       throw;
    }
    finnaly
    {
       if (_icc.State == CommunicationState.Openned)
       {
          try { _icc.Close(); }
          catch { _icc.Abort(); }
       }
    }

    Awaiting reply,

    Thank you,

    Trung Nguyen


    Thursday, February 23, 2017 3:12 AM

All replies

  • Hi Trung,

    >> if it run asynchronously timeout error will not be thrown and the client will wait until it is completed.

    Will the async option be completed or throw any other exception? I made a simple test with this, and I could reproduce your issue. The result will be send to client no matter whether it is timeout. I assume it is related with async pattern. When implementing WCF in async, client send a request to service, it would not wait for service to response, and service will response to client until it finished the request.

    If you need to stop it in a certain time, I would suggest you use sync option.

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, February 24, 2017 6:24 AM
  • Hi Edward,

    Thank you for your support. As you mentioned "The result will be sent to client no matter whether it is timeout", so, how to catch timeout exception with async operation and ReliableSession=true (if i set ReliableSession=False, i catch timeout exception as normal) ?

    Regards,

    Trung Nguyen

    Friday, February 24, 2017 11:08 AM
  • Hi Trung,

    For timeout in reliable messaging, I would suggest you try InactivityTimeout.

    Here is a simple code which will produce System.ServiceModel.CommunicationException with The inactivity timeout of (00:00:03) has been exceeded error message.

    var _bd = new WSHttpBinding();
                _bd.Security.Mode = SecurityMode.None;
                _bd.ReliableSession.Enabled = true;
                _bd.ReliableSession.InactivityTimeout = TimeSpan.FromSeconds(3);
                var _factory = new ChannelFactory<IWCFAsync>(_bd, "http://localhost:1045/WCFAsync.svc");
                var _conn = _factory.CreateChannel();
                var _icc = _conn as IContextChannel;            
                try
                {
                    string result = "";
                    _icc.Open();
    
                    result= await _conn.GetAsync(123);
                    MessageBox.Show(result);
                }
                catch(CommunicationException ee)
                {
                    //throw;
                    MessageBox.Show(ee.Message.ToString());
                }
                finally
                { 
                    if (_icc.State == CommunicationState.Opened)
                    {
                        try { _icc.Close(); }
                        catch { _icc.Abort(); }
                    }
                }

    SendTimeout is applied to Binding, and InactivityTimeout is applied to ReliableSession.

    Best Regards,

    Edward

                   

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, February 27, 2017 5:29 AM
  • Hi Edwards,

    Thank you for your support. I know the InactivityTimeout is used for ReliableSession. But, there is a problem, setting InactivityTimeout value must be done before creating channel and it cannot be changed during the lifetime of channel. I want to change the value of InactivityTimeout depend on the context in a session (similar to OperationTimeout). Is it possible?

    Regards,

    Trung Nguyen

    Monday, February 27, 2017 6:45 AM
  • Hi Trung,

    As you know, InactivityTimeout should be set before creating channel and it could not be changed during lifetime of channel.

    For all the timeout settings, only InactivityTimeout affect the time for ReliableSession at client side. Based on your description, I think the settings at service would not meet your requirement since you need to change depend on the context.

    I am afraid using Sync option would be the only option.

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, February 27, 2017 8:33 AM
  • Ok. Thank you Edward.

    Regards,

    Trung Nguyen

    Monday, February 27, 2017 9:35 AM