Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report for Bug 37342 on
GitHub or Developer Community if you have new
information to add and do not yet see a matching new report.
If the latest results still closely match this report, you can use the
In special cases on GitHub you might also want the comments:
GitHub Markdown with public comments
Created attachment 14418 [details]
[Mono 4.2] ArgumentOutOfRangeException when using ChannelFactory if BasicHttpBinding.SendTimeout is set to TimeSpan.MaxValue
## Regression status: a "new feature" in Mono 4.2 has exposed a new problem
In Mono 4.0.5 (1d8d582) and earlier, the local `value` variable was always "60000" during the call to `System.Net.HttpWebRequest.set_Timeout()` that happened during a `BasicHttpBinding` WCF channel setup.
In Mono 4.2 and later, if the user sets `BasicHttpBinding.SendTimeout`, that number now propogates correctly into the `value` variable in the `set_Timeout()` method. Unfortunately, this exposes a place where the .NET behavior differs from the current Mono behavior.
In .NET, you can set `BasicHttpBinding.SendTimeout` to `TimeSpan.MaxValue` and everything works without error.
In Mono, using `TimeSpan.MaxValue` causes an integer overflow, and leads to an ArgumentOutOfRangeException.
There's a chance this is an arbitrary implementation decision in .NET, so Mono's behavior might not necessarily be "wrong." For example, the documentation for `Binding.SendTimeout`  does not specify that `TimeSpan.MaxValue` is a valid input value.
## Steps to replicate
1. Build the project:
> $ xbuild /t:Build /p:Configuration=Debug ConsoleWCFClient.csproj
2. Run the resulting `.exe`:
> $ mono bin/Debug/ConsoleWCFClient.exe
### Mono 4.2 (39edf24)
If you set Xamarin Studio to break on all exceptions, you can see that the program fails because `TimeSpan.MaxValue` overflows the integer `value` variable at:
> System.Net.HttpWebRequest.set_Timeout(int value) in /private/tmp/source-mono-mac-4.2.0-branch/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.1/mcs/class/System/System.Net/HttpWebRequest.cs:605
> System.ServiceModel.Channels.HttpRequestChannel.BeginProcessRequest(System.ServiceModel.Channels.HttpRequestChannel.HttpChannelRequestAsyncResult result) in /private/tmp/source-mono-mac-4.2.0-branch/bockbuild-mono-4.2.0-branch/profiles/mono-mac-xamarin/build-root/mono-4.2.1/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs:128
#### The stack trace output directly on the standard output of the program is less informative
> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
> Parameter name: value
> at (wrapper managed-to-native) System.Object:__icall_wrapper_mono_remoting_wrapper (intptr,intptr)
> at (wrapper remoting-invoke) TempConvertSoap:EndFahrenheitToCelsius (System.IAsyncResult)
> at ConsoleWCFClient.MainClass.OnTestMethodCompleted (IAsyncResult asyncResult) <0x2cc9828 + 0x000aa> in <filename unknown>:0
### .NET 4.5 on Windows
The program completes successfully with the following output:
> Sent request...
> The converted value is: 37
Taking a guess that the .NET stack would also call `System.Net.HttpWebRequest.set_Timeout()`, I set a symbolic breakpoint on that method in Visual Studio. I discovered that the code that sets the timeout in .NET uses some extra logic that prevents the WCF channel from trying to set a timeout that overflows the integer. In particular, `HttpWebRequest.set_Timeout()` is called indirectly via `HttpChannelUtilities.SetRequestTimeout()` . And that helper method in turn uses another `TimeoutHelper.ToMilliseconds()` helper method  that cleans up the maximum return value, avoiding the overflow.
*** Bug 37338 has been marked as a duplicate of this bug. ***