I'm developing a solution with a WCF service and a client that uses the service. Sometimes I'm debugging the service, sometime the client, and sometimes both.
During debugging I get a TimeoutException with additional information
Additional information: The request channel timed out while waiting for a reply after 00:00:59.9950000. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.
The reason if of course that my server is waiting at a breakpoint instead of answering the question.
During debugging I want longer timeouts, preferably without creating a new configuration for my service client, because if other values of this configuration would change, the changer would have to remember that a special configuration for debugging was created.
I think it is something like:
private IMyServiceInterface CreateServiceChannel()
{
var myServiceClient = new MyServiceClient(); // reads from configuration file
if (Debugger.IsAttached)
{
// Increase timeouts to enable slow debugging
...
}
return (IMyServiceInterface)myServiceClient;
}
According to MSDN Binding.SendTimeout Property is used for something else:
SendTimeout gets or sets the interval of time provided for a write operation to complete before the transport raises an exception.
Therefore I'd rather not change this value if not needed.
Is SendTimeout really the best timeout to increase, or is there something like a TransactionTimeout, the timeout between my question and the receipt of the answer?
How to change the timeout programmatically
The article All WCF timouts explained states that indeed there is something like a transaction timeout: IContextChannel.OperationTimeout
The operation timeout covers the whole service call (sending the request, processing it and receiving a reply). In other words, it defines the maximum time a service call is active from a client’s point of view. If not set, WCF initializes the operation timeout with the configured send timeout.
This explains why the TimeoutException that is thrown advises to change the send timeout.
However, it is possible to change the operation timeout without changing the send timeout:
var myServiceClient = new MyServiceClient(); // reads from configuration file
if (Debugger.IsAttached)
{ // Increase timeouts to enable slow debugging:
IContextChannel contextChannel = (IContextChannel)myServiceClient.InnerChannel;
// InnerChannel is of type IClientChannel, which implements IContextChannel
// set the operation timeout to a long value, for example 3 minutes:
contextChannel.OperationTimeout = TimeSpan.FromMinutes(3);
}
return (IMyInterface)myService;
Related
We are using http sys web server to host web api service. Business requires to limit maximum number of concurrent connections. MaxConnections configuration property used for that purpose:
services.Configure<HttpSysOptions>(options =>
{
options.MaxConnections = Configuration.GetValue<long?>("MaxConnections");
});
But in case when concurrent connection limit reached all new connections got dropped on a socket level. Is it possible to change this behaviour so server accepts the request and returns 4xx or 5xx response to the client?
I have finally managed to find a solution: there is Http503Verbosity property in options. By default it is set to Http503VerbosityLevel.Basic but if to change it to Http503VerbosityLevel .Limited or Http503VerbosityLevel.Full 503 response will be returned for requests above limit. So my code looks like this now:
services.Configure<HttpSysOptions>(options =>
{
options.MaxConnections = Configuration.GetValue<long?>("MaxConnections");
options.Http503Verbosity = Http503VerbosityLevel.Full;
});
While I'm executing the server method asynchronously, getting this Timeout exception continuously.
"Additional information:
This request operation sent to http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous
did not receive a reply within the configured timeout (00:01:00).
The time allotted to this operation may have been a portion of a longer timeout.
This may be because the service is still processing the operation or
because the service was unable to send a reply message.
Please consider increasing the operation timeout
(by casting the channel/proxy to IContextChannel and setting the OperationTimeout property)
and ensure that the service is able to connect to the client."
Could someone mention how to increasing the operation timeout
by casting the channel/proxy to IContextChannel and setting the OperationTimeout property ?
This is my existing binding (with client) code.
DuplexChannelFactory<IPortal> datafactory;
NetTcpBinding tcpBinding = new NetTcpBinding();
String sURL = "net.tcp://localhost:8002/MyPortal";
tcpBinding.MaxReceivedMessageSize = System.Int32.MaxValue;
tcpBinding.ReaderQuotas.MaxArrayLength = System.Int32.MaxValue;
datafactory = new DuplexChannelFactory<IPortal>(this,tcpBinding, sURL);
Portal = datafactory.CreateChannel();
If you follow the link in the error (schemas.microsoft.com etc etc) it serves up:
Theresource you are looking for has been removed, had its name
changed, or is temporarily unavailable.
Why are you looking up MS? It sounds like you've got some config data wrong somewhere. If you search your source for that url, what do you find? Does it look sensible?
When using a CloudTableClient, is there a way to specify a client side timeout?
The TableRequestOptions RetryPolicy and ServerTimeout control the number of retry attempts, the delay between attempts, and the storage service side timeout, but don't seem to cover a client side per-attempt timeout (like the HttpClient.Timeout property).
My concern with relying on the ServerSideTimeout is with delays connecting to the actual server.
When using a CloudTableClient, is there a way to specify a client side timeout?
The MaximumExecutionTime property of TableRequestOptions could help us specific the maximum execution time for all potential retries for the request include the time used by client side and server side.
tableClient.DefaultRequestOptions.MaximumExecutionTime = new TimeSpan(0, 0, 0, 0, 100);
A exception will throw if the request can't be handled in the specific time.
Microsoft.WindowsAzure.Storage.StorageException: 'The client could not finish the operation within specified timeout.'
like the HttpClient.Timeout property
The Timeout property of HttpClient also specific all the execution time before the response came back.
I'm hoping to find a per-retry timeout.
I suggest you use the MaximumExecutionTime. If you need a client side DNS resolve timeout, you could get or set the DnsRefreshTimeout property of ServicePointManager.
ServicePointManager.DnsRefreshTimeout = 4*60*1000; // 4 minutes
I have a Azure Webjob which hits a WebApi. The WebApi sends back an acknowledgement in 4 - 5mins. So, I have declared the TimeOut for the HttpClient to be at 10 mins.
Now, if the WebApi is returning the response in less than 4 mins, it works fine. But if the WebApi is returning the response for a request in 4 min 30 sec, the azure webjob is not getting this acknowledgement. Instead, the HttpClient on the WebJob is waiting for 10 mins, and then timing out. Is there some kind of a time out on the Webjob that I'm missing?
There is a 230 second timeout for requests that are not sending any data back. Please see the answer of #David Ebbo in following thread.
https://social.msdn.microsoft.com/Forums/en-US/17305ddc-07b2-436c-881b-286d1744c98f/503-errors-with-large-pdf-file?forum=windowsazurewebsitespreview
There is a 230 second (i.e. a little less than 4 mins) timeout for requests that are not sending any data back. After that, the client gets the 500 you saw, even though in reality the request is allowed to continue server side.
So the issue of not receiving response from Web API is related to the timeout limit of Azure Web App. I also test it on my side. Though I set executionTimeout as 10min in web.config.
<httpRuntime targetFramework="4.6" executionTimeout="600" />
If the time of sending response from service side need more than 230s. I will get a 500 error on my client side.
public IEnumerable<string> Get()
{
Thread.Sleep(270000);
return new string[] { "value1", "value2" };
}
I suggest you accept the suggestion of #Thomas. Writing your response to a queue from your Web API and get the response which you needed from the queue.
So, is there no method to bypass this timeout?
The 230 sec limit also could be proved in following article.
there is a general idle request timeout that will cause clients to get disconnected after 230 seconds.
https://github.com/projectkudu/kudu/wiki/Configurable-settings
I haven't found any ways to modify this timeout for Azure Web App. Please try the workarounds which I mentioned above.
If you are executing a long running task or function in the context of BrokeredMessages, they have a timeout hard coded to 5 minutes.
Utilizing Task I place my long running function inside one and passing it to this function to run and "relock" the BrokeredMessage:
/// <summary>
/// Maximum time lockout for a BrokeredMessage is 5 minutes. This allows the
/// timer to relock every 4 minutes while waiting on Task parameter to complete.
/// </summary>
/// <param name="task"></param>
/// <param name="message"></param>
private void WaitAndRelockMessage( Task task, BrokeredMessage message )
{
var myTimer = new Timer( new TimerCallback( RelockMessage ), message, 240000, 240000 );
task.Wait();
myTimer.Dispose();
}
private void RelockMessage( object message )
{
try { ((BrokeredMessage)message).RenewLock(); }
catch( OperationCanceledException ) { }
}
Sample Usage:
var task = Task.Run( async () => { await m_service.doWork(); } );
WaitAndRelockMessage(task, message);
I have a WCF client with the following piece of code written:
MyClient myClient = new MyClient();
string id = Guid.NewGuid();
string result = myClient.Foo(id);
Console.WriteLine(result);
This works, but I want to add a time limit for the service call, so an exception will be thrown if the operation takes too long. I tried adding the timeout in the config file at the binding element like so:
<basicHttpBinding>
<binding
receiveTimeout="00:00:05"
sendTimeout="00:00:05"
</binding>
</basicHttpBinding>
This doesn't seem to work sadly.
I also tried setting it manually in the code file like so:
MyClient myClient = new MyClient();
myClient.Endpoint.Binding = new BasicHttpBinding()
{
SendTimeout = new TimeSpan(0, 0, 5),
ReceiveTimeout = new TimeSpan(0, 0, 5)
};
string id = Guid.NewGuid();
string result = myClient.Foo(id);
Console.WriteLine(result);
But again, it doesn't seem to work.
I tested it with a really slow service, and after 20 minutes it finally returned with the (correct) answer, but a timeout exception was not thrown.
Is it possible that the WCF service I am trying to reach is somehow blocking timeouts?
I've been down this rabbit hole before. I think OperationTimeout might be what you're looking for.
(myClient as IClientChannel).OperationTimeout = TimeSpan.FromSeconds(5);
Answering my own question, almost a year later.
I originally left this bug unresolved since it used to rarely happen. It resurfaced recently so I had to dig into it once again.
As I found out, a TimeoutException wasn't thrown, simply because the SOAP request finished successfully. A timeout is only honoured from the moment the request goes out until a response returns. I verified that using fiddler. But still my code was hanging for hours.
It appears the part blocking my code was simply the parsing of the SOAP response. The default WCF parser was simply hanging forever when trying to parse specific responses as XElement.
I'm playing around with using different custom parsers and will post the results when I finish.