Timeout exception - c# ( wcf ) - c#

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?

Related

How to change http.sys web server response when maxconnection limit reached

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;
});

Handle NormalizePoisonException in MSMQ Integration Binding

Good evening,
I have an MSMQ queue that is pushing messages to a WCF service using msmqIntegrationBinding.
The receiveErrorHandling property is set to the default of "Fault".
Occasionally, MSMQ has a hissy fit trying to deserialise a message:
System.ServiceModel.ProtocolException: An error was encountered while deserializing the message. The message cannot be received.
System.Runtime.Serialization.SerializationException: An error occurred while deserializing an MSMQ message's XML body. The message cannot be received. Ensure that the service contract is decorated with appropriate [ServiceKnownType] attributes or the TargetSerializationTypes property is set on the MsmqIntegrationBindingElement.
at System.ServiceModel.Channels.MsmqDecodeHelper.XmlDeserializeForIntegration(MsmqIntegrationChannelListener listener, Stream stream, Int64 lookupId)
at System.ServiceModel.Channels.MsmqDecodeHelper.DeserializeForIntegration(MsmqIntegrationChannelListener listener, Stream bodyStream, MsmqIntegrationMessageProperty property, Int64 lookupId)
The message never reaches the method in the service:
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void ProcessMessage(MsmqMessage<MyMessage> msg)
{...
The service has this attribute:
[ServiceKnownType(typeof(MyMessage))]
There is a dead letter queue set in the binding:
<msmqIntegrationBinding>
<binding name="MyBinding" serializationFormat="Xml" exactlyOnce="false" deadLetterQueue="Custom" customDeadLetterQueue="msmq.formatname:DIRECT=OS:.\private$\services/deadLetterQueue" useMsmqTracing="true" receiveErrorHandling="Fault">
The message is not processed by the WCF service and is dumped straight into the Journal queue. It is not left in the Messaging queue or moved to the dead letter queue.
I have tried implementing an IErrorHandler as detailed here but it doesn't reach it.
When receiving a message from MSMQ in the traditional way...
MessageQueue msMq = new MessageQueue(_queueName);
msMq.Formatter = new XmlMessageFormatter(new Type[] { typeof(MyMessage) });
Message m = msMq.Receive();
It works if I set the formatter as above. But when despite serializationFormat="Xml" being set in the binding, it still fails to deserialise.
I've missed something for sure. I've Googled everywhere. Any help is greatly appreciated.
Thanks.
After some intense Googling I came across two issues:
1) If you want transactions in MSMQ to work, make sure that whoever setup the queue made it a transactional queue when they created it. (Sigh..)
2) In the IErrorHandler example, I wasn't concentrating with my copying and pasting (Less coffee, more sleep) and put the ApplyDispatchBehavior logic into Validate by mistake, where no ChannelDispatchers exist yet (Extra sigh...).
foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
What a kerfluffle!

CloudTableClient client side timeout

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

ClientBase EndPoint Binding SendTimeout ReceiveTimeout: how to change while debugging

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;

Why is the WCF Client timeout ignored

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.

Categories