[System.ServiceModel] Don't use DateTime.Now for measuring elapsed time
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel / ClientRuntimeChannel.cs
index 043b2ab7af08df3875689382a09e41e1210750f3..df7a9e4cd9742a07869d9f9be7ada306ca16312e 100644 (file)
@@ -67,6 +67,8 @@ namespace System.ServiceModel.MonoInternal
                TimeSpan default_open_timeout, default_close_timeout;
                IChannel channel;
                IChannelFactory factory;
+               TimeSpan? operation_timeout = null;
+               ChannelFactory channel_factory;
 
                #region delegates
                readonly ProcessDelegate _processDelegate;
@@ -86,6 +88,7 @@ namespace System.ServiceModel.MonoInternal
                        ChannelFactory channelFactory, EndpointAddress remoteAddress, Uri via)
                        : this (endpoint.CreateClientRuntime (null), endpoint.Contract, channelFactory.DefaultOpenTimeout, channelFactory.DefaultCloseTimeout, null, channelFactory.OpenedChannelFactory, endpoint.Binding.MessageVersion, remoteAddress, via)
                {
+                       channel_factory = channelFactory;
                }
 
                public ClientRuntimeChannel (ClientRuntime runtime, ContractDescription contract, TimeSpan openTimeout, TimeSpan closeTimeout, IChannel contextChannel, IChannelFactory factory, MessageVersion messageVersion, EndpointAddress remoteAddress, Uri via)
@@ -108,7 +111,6 @@ namespace System.ServiceModel.MonoInternal
 
                        // default values
                        AllowInitializationUI = true;
-                       OperationTimeout = TimeSpan.FromMinutes (1);
 
                        if (contextChannel != null)
                                channel = contextChannel;
@@ -322,8 +324,10 @@ namespace System.ServiceModel.MonoInternal
                        }
                }
 
-               [MonoTODO]
-               public TimeSpan OperationTimeout { get; set; }
+               public TimeSpan OperationTimeout {
+                       get { return this.operation_timeout ?? (channel_factory != null ? channel_factory.Endpoint.Binding.SendTimeout : DefaultCommunicationTimeouts.Instance.SendTimeout); }
+                       set { this.operation_timeout = value; }
+               }
 
                public IOutputSession OutputSession {
                        get {
@@ -379,7 +383,6 @@ namespace System.ServiceModel.MonoInternal
 
                protected override void OnClose (TimeSpan timeout)
                {
-                       DateTime start = DateTime.Now;
                        if (channel.State == CommunicationState.Opened)
                                channel.Close (timeout);
                }
@@ -457,8 +460,6 @@ namespace System.ServiceModel.MonoInternal
                        if (p == parameters)
                                return retval;
 
-                       if (p.Length != parameters.Length)
-                               throw new InvalidOperationException ();
                        Array.Copy (p, parameters, p.Length);
                        return retval;
                }
@@ -591,9 +592,9 @@ namespace System.ServiceModel.MonoInternal
                        // FIXME: implement ConcurrencyMode check:
                        // if it is .Single && this instance for a callback channel && the operation is invoked inside service operation, then error.
 
-                       DateTime startTime = DateTime.Now;
+                       DateTime startTime = DateTime.UtcNow;
                        OutputChannel.Send (msg, timeout);
-                       return ((IDuplexChannel) channel).Receive (timeout - (DateTime.Now - startTime));
+                       return ((IDuplexChannel) channel).Receive (timeout - (DateTime.UtcNow - startTime));
                }
 
                internal IAsyncResult BeginRequest (Message msg, TimeSpan timeout, AsyncCallback callback, object state)