Silverlight 4 Ria Services Timeout Issues - silverlight

I am making a call from my Silverlight client into my DomainService that normally takes about 2 minutes. I need to extend the timeout value of the endpoint to 5 minutes to be safe, but it appears to ignore the setting and I can't find out why. Here is how I am creating my DomainContext in my client:
MyDomainContext context = new MyDomainContext();
((WebDomainClient<MyDomainContext.IMyDomainServiceContract>)context.DomainClient).ChannelFactory.Endpoint.Binding.ReceiveTimeout = new TimeSpan(0, 5, 0);
context.Search(_myParms, p =>
{
if (p.HasError)
{
// Handle errors
}
// Should take about 2 min. to get here, but times out before
}, null);
I have tried setting the ReveiveTimeout and SendTimeout both, but I always get the error at exactly 1 minute.
Can someone tell me what I am doing wrong?
EDIT: This is the exact error I am getting:
{System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.<>c_DisplayClass5.b_4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c_DisplayClass2.b_0(Object sendState)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)}
I have also tested to make sure it's not something in my service. At present, I just have my service run a while loop. Again, I get this error at exactly one minute.
Thanks,
-Scott

You should implement partial method OnCreated() of MyDomainContex class.
Sample:
public partial class TestDomainContext
{
partial void OnCreated()
{
var proxy = (WebDomainClient<Test.Server.Services.TestDomainContext.ITestDomainServiceContract>)this.DomainClient;
proxy.ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 5, 0);
}

This problem is one of the pain points in Silverlight.
I prefer an extension method for something like this rather than creating delicate partial classes.
See the solution here:
http://blogs.msdn.com/b/kylemc/archive/2010/11/03/how-to-change-the-request-timeout-for-wcf-ria-services.aspx
if your using prism you can inject as follows:
_unityContainer.RegisterType<SurveyModuleContext>(new InjectionFactory(c => CreateSurveyContext()));
private object CreateSurveyContext()
{
var context = new SurveyModuleContext();
context.ChangeWcfSendTimeout(new TimeSpan(0, 10, 0));
return context;
}
public static class DomainContextExtensions
{
public static void ChangeWcfSendTimeout(this DomainContext context,
TimeSpan sendTimeout)
{
PropertyInfo channelFactoryProperty =
context.DomainClient.GetType().GetProperty("ChannelFactory");
if (channelFactoryProperty == null)
{
throw new InvalidOperationException(
"There is no 'ChannelFactory' property on the DomainClient.");
}
ChannelFactory factory = (ChannelFactory)channelFactoryProperty.GetValue(context.DomainClient, null);
factory.Endpoint.Binding.SendTimeout = sendTimeout;
}
}
You can see in this screenshot that the solution does indeed work. (2m 1s) call

Could it be a request timeout on the server side web application that hosts the domain service? Check the settings of the web application where the service runs or the application pool.

Related

Only one usage of each socket address (protocol/network address/port) is normally permitted

The last few weeks we have been experiencing this error message while using the Azure Search SDK (1.1.1 - 1.1.2) and performing searches.
We consume the Search SDK from internal APIs (deployed as Azure Web Apps) that scale up-down based on traffic (so there could be more than 1 instance of the APIs doing the searches).
Our API queries 5 different indexes and maintains an in-memory copy of the SearchIndexClient object that corresponds to each index, a very simple implementation would look like:
public class AzureSearchService
{
private readonly SearchServiceClient _serviceClient;
private Dictionary<string, SearchIndexClient> _clientDictionary;
public AzureSearchService()
{
_serviceClient = new SearchServiceClient("myservicename", new SearchCredentials("myservicekey"));
_clientDictionary = new Dictionary<string, SearchIndexClient>();
}
public SearchIndexClient GetClient(string indexName)
{
try
{
if (!_clientDictionary.ContainsKey(indexName))
{
_clientDictionary.Add(indexName, _serviceClient.Indexes.GetClient(indexName));
}
return _clientDictionary[indexName];
}
catch
{
return null;
}
}
public async Task<SearchResults> SearchIndex(SearchIndexClient client, string text)
{
var parameters = new SearchParameters();
parameters.Top = 10;
parameters.IncludeTotalResultCount = true;
var response = await client.Documents.SearchWithHttpMessagesAsync(text, parameters, null, null);
return response.Body;
}
}
And the API would invoke the service by:
public class SearchController : ApiController
{
private readonly AzureSearchService service;
public SearchController()
{
service = new AzureSearchService();
}
public async Task<HttpResponseMessage> Post(string indexName, [FromBody] string text)
{
var indexClient = service.GetClient(indexName);
var results = await service.SearchIndex(indexClient, text);
return Request.CreateResponse(HttpStatusCode.OK, results, Configuration.Formatters.JsonFormatter);
}
}
We are using SearchWithHttpMessagesAsync due to a requirement to receive custom HTTP headers instead of the SearchAsync method.
This way we avoid opening/closing the client under traffic bursts. Before using this memory cache (and wrapping each client on a using clause) we would get port exhaustion alerts on Azure App Services.
Is this a good pattern? Could we be receiving this error because of the multiple instances running in parallel?
In case it is needed, the stack trace shows:
System.Net.Http.HttpRequestException: Only one usage of each socket address (protocol/network address/port) is normally permitted service.ip.address.hidden:443
[SocketException:Only one usage of each socket address (protocol/network address/port)is normally permitted service.ip.address.hidden:443]
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure,Socket s4,Socket s6,Socket& socket,IPAddress& address,ConnectSocketState state,IAsyncResult asyncResult,Exception& exception)
[WebException:Unable to connect to the remote server]
at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult,TransportContext& context)
at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
EDIT: We are also receiving this error A connection attempt failed because the connected party did not properly respond after a period of time:
System.Net.Http.HttpRequestException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond service.ip.address.hidden:443
[SocketException:A connection attempt failed because the connected party did not properly respond after a period of time,or established connection failed because connected host has failed to respond service.ip.address.hidden:443]
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure,Socket s4,Socket s6,Socket& socket,IPAddress& address,ConnectSocketState state,IAsyncResult asyncResult,Exception& exception)
[WebException:Unable to connect to the remote server]
at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult,TransportContext& context)
at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
As implemented in the code in your question, the cache will not prevent port exhaustion. This is because you're instantiating it as a field of the ApiController, which is created once per request. If you want to avoid port exhaustion, the cache must be shared across all requests. To make it concurrency-safe, you should use something like ConcurrentDictionary instead of Dictionary.
The "connection attempt failed" error is likely unrelated.

WCF service in WPF self host application crash when I throw a fault exception (async methods)

I have a service hosted in a WPF application with an async method with the Begin/end methods, and when I catch an exception in the service, I want to throw a faultException to warn to the client.
However, when I try to throw the faultException, the host application crash, shutdown suddenly.
In my repository, I catch the UpdateException, then, I create a custom exception, UniqueKeyException, that is throw to the caller. The caller is an auxiliar method that is called in the Begin method.
This auxiliar method, catch the UniqyeKeyException and only do a "throw", that is capture in the try/catch block of my end method. Here there is something that I don't understand, why in the end mehod this exception is catched in the block of AgregateException instead of the UniqueKeyException.
Well, anyway, in the catch block of the end method, in the AgregateException block, I check if the innerException is UniqueKeyException, if it is true, I create an object UniqueKeyArgs (a custom class with the information to send to the client), create a FaultException and finally do the throw FaultException. It is in this step, the throw, where the host application crash.
I think that I have all configure correctly, because my custom class UniqueKeyArgs is decorate as Datacontract and its properties as DataMember, in the app.config of my host application I configure the behavior to include exception details and in the contract I decorate it with faultContract.
Why the application crash?
My code is the following:
REPOSITORY
public List<Usuers> updateUsers(List<Users> paramUsers)
{
....
catch(UpdateException ex)
{
SqlException innerEx = (SqlException)ex.InnerException;
//Code 2627 is Unique Key exception from SQL Server.
if (innerEx != null && innerEx.Number == 2627)
{
//I create the conditions of searching
ConditionsUsers conditions = new conditions();
conditions.UserName = (Users)ex.StateEntries[0].Entity).userName;
//Search for the existing user
Users myUser = getUser(conditions);
string message = "the user " + conditions.userName + " exists.";
throw new UniqueKeyException(message, myUser);
}
throw;
}
SERVICE IMPLEMENTATION
//This is my auxiliar method, called in the Begin method.
private submitUpdates()
{
....
catch(UniqueKeyException ex)
{
//The code enter here
throw;
}
}
public IAsyncResult BeginUpdateUsers(List<users> paramUsers, AsyncCallback callback, object state)
{
Task<List<Users>> myTask= Task<List<Users>>.Factory.StartNew(p => sumbmitUpdates(paramUsers), state);
return myTask.ContinueWith(res => callback(myTask));
}
public List<Users> EndUpdateusers(IAsyncResult result)
{
try
{
return ((Task<List<Users>>)result).Result;
}
//Why agregateException and not is catched in the UniqueKeyException ???
catch(AgregateException ex)
{
if (innerExceptions[0] is UsuariosValorUnicoException)
{
//I assign manually the data to debug, to discard other problems.
Users myUser = new Users();
myUser.UserName = "Jhon";
myUser.Password = "pass123";
UniqueKeyArgs myArgs = new UniqueUserArgs("unique key error", myUser);
FaultException<UniqueKeyArgs> myException = new FaultException<UniqueKeyArgs>(myArgs);
//Crash here, in the throw myException
throw myException;
}
}
throw;
}
MY CONTRACT
[FaultContract(typeof(UniqueKeyArgs))]
IAsyncResult BeginUpdateUsers(List<Users> paramUser, AsyncCallback callback, object state);
List<Users> EndUpdateUsers(IAsyncResult result);
Crash when I throw myException in the End method.
I see in this post that the solution is catch the exception in the host application too, not only in the service object. However, this solution uses Application.ThreadException, that belong to System.Windows.Forms namespace, and I am using a WPF application.
How could I send the exception to the client from a service hosted in a WPF application?
Thanks.
EDIT1: well, I am use a try/catch block in the line where I throw the exception and I see that the error is that I have not indicated a reason, so when I create my FaultException I do:
FaultException<UniqueKeyArgs> myException = new FaultException<UniqueKeyArgs>(myArgs, new FaultReason("DummyReason");
In this case, the exception message is "DummyReason", the message that I set in the FaultReason, so it says me nothing. The FaultException is not throw, and throw the generic exception to the client.
In this case the host application does not shutdown, but close the connection with the client and I have to reconnect.
It seems that the problem is the creaton of the FaultException, but I don't see the problem.
#Roeal suggests that perhaps is only possible to use faultException with synch methods, but in this link I can see an example in which is used with async methods. I have seen others examples, is not the unique.
Thanks.
EDIT2: I solve my problem. My problem is that in the FaultException, T is an object that have a property that was a self tracking entity, and this is a problem, if I am not wrong, I only can use basic types as properties of the exception.
Then, in the exception, I have implmemented ISerialize. It's needed to be able to send the information to the client, without this, the client receives an exception.Detail with null properties.
Did you also declare the synchronous operation in your service contract? In that case, maybe this helps:
If fault contracts are defined on the service operation contract, the FaultContract attribute should be applied only on the synchronous operations.
-- Juval Lowy, "Programming WCF Services 3rd Edition" (p456)
I solve my problem. My problem is that in the FaultException, T is an object that have a property that was a self tracking entity, and this is a problem, if I am not wrong, I only can use basic types as properties of the exception.
Then, in the exception, I have implmemented ISerialize. It's needed to be able to send the information to the client, without this, the client receives an exception.Detail with null properties.

Silverlight Enabled WCF Service Exception Handling

I've got a Silverlight enabled WCF web service set up and I'm connecting to it from my Silverlight application.
The Service is not written using the ASync pattern but Silverlight generates the async methods automatically.
I have a method that within my service that has a chance of throwing an exception I can catch this exception but I'm not sure of the best way of handling this exception, I've noticed that the event args of the completed method contain an error property.
Is is possible to set the value of this error property?
Example Method
public class service
{
[OperationContract]
public Stream getData(string filename)
{
string filepath = HostingEnvironment.MapPath(filename);
FileInfo fi = new FileInfo(filenpath);
try
{
Stream s = fi.Open(FileMode.Open);
return s;
}
catch (IOException e)
{
return null;
}
}
}
Silverlight Code
btnFoo_Click(object sender, RoutedEventArgs e)
{
ServiceClient svc = new ServiceClient();
svc.getDataCompleted += new EventHandler<getDataCompletedEventArgs>(getData_Completed);
svc.getDataAsync("text.txt");
}
void getData_Completed(object sender, getDataCompletedEventArgs e)
{
e.Error //how can i set this value on the service?
}
Finally if the service is offline or times out is there anyway to catch this exception before it reaches the UnhandledException method within App.xaml?
Thanks
Since silverlight is using services asyncronously you dont get a synchronous exception throw, but instead it is stored in e.Error property, that you need to check in your ServiceCallCompleted method.
To answer your question
how can i set this value on the service?
Simply throw an exception on server and it can be enough given several other conditions.
You may want to introduce FaultContract on your WCF service method, and throw FaultException<T> which is a common way to deal with errors in WCF.
However fault result in return code 500 and silverlight won't be able to get response with such status code and have access to Fault object, even if you add that attribute to service.
This can be solved using several approaches.
Use the alternative client HTTP stack: You can register an alternative HTTP stack by using the RegisterPrefix method. See below for an outline of how to do this. Silverlight 4 provides the option of using a client HTTP stack which, unlike the default browser HTTP stack, allows you to process SOAP-compliant fault messages. However, a potential problem of switching to the alternative HTTP stack is that information stored by the browser (such as authentication cookies) will no longer be available to Silverlight, and thus certain scenarios involving secure services might stop working, or require additional code to work.
Modify the HTTP status code: You can modify your service to return SOAP faults with an HTTP status code of 200, Silverlight 4 so that faults will be processed successfully. How to do this is outlined below. Note that this will make the service non-compliant with the SOAP protocol, because SOAP requires a response code in the 400 or 500 range for faults. If the service is a WCF service, you can create an endpoint behavior that plugs in a message inspector that changes the status code to 200. Then you can create an endpoint specifically for Silverlight consumption, and apply the behavior there. Your other endpoints will still remain SOAP-compliant.
Faults in silverlight
Creating and Handling Faults in Silverlight
OR
[DataContract]
public class MyError
{
[DataMember]
public string Code { get; set; }
[DataMember]
public string Message { get; set; }
[DataMember]
public DateTime Time { get; set; }
}
public class service
{
[OperationContract]
public Stream getData(string filename, out MyError myError)
{
myError = null;
string filepath = HostingEnvironment.MapPath(filename);
FileInfo fi = new FileInfo(filenpath);
try
{
Stream s = fi.Open(FileMode.Open);
return s;
}
catch (IOException e)
{
myError = new MyError() { Code = "000", Message = ex.Message, Time = DateTime.Now };
return null;
}
}
}
I wish successful projects

Silverlight 4 WCF Ria Service Timeout

I’ve asked this question before without getting to the solution, but since I have done a lot more testing and debugging, and have new information, I figured I would ask again in hopes of getting to the bottom of this once and for all.
My domain service is timing out after 1 minute. I have read all the posts and seen how to create a partial class and explicitly set timeout values, and I have done exactly that, but I still get timed out after one minute. The caveat to this is that after explicitly setting the timeout in my partial class/method, I no longer receive the standard timeout error. Instead I get this:
{System.Net.WebException: The remote
server returned an error: NotFound.
---> System.Net.WebException: The remote server returned an error:
NotFound. at
System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult
asyncResult) at
System.Net.Browser.BrowserHttpWebRequest.<>c_DisplayClass5.b_4(Object
sendState) at
System.Net.Browser.AsyncHelper.<>c_DisplayClass2.b_0(Object
sendState) --- End of inner exception
stack trace --- at
System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback
beginMethod, Object state) at
System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult
asyncResult) at
System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult
result)}
Here is my partial class that I set the timeout values in. I have debugged this and know for certain that these values are being set prior to making the call into the service. The service method I am working with is TestTimeout(). It does nothing but sit and wait until the above exception is thrown - exactly one minute after the call.
public partial class MyDomainContext
{
partial void OnCreated()
{
var proxy = (WebDomainClient<MyDomainContext.IMyDomainServiceContract>)this.DomainClient;
proxy.ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 5, 0);
proxy.ChannelFactory.Endpoint.Binding.ReceiveTimeout = new TimeSpan(0, 5, 0);
proxy.ChannelFactory.Endpoint.Binding.CloseTimeout = new TimeSpan(0, 5, 0);
proxy.ChannelFactory.Endpoint.Binding.OpenTimeout = new TimeSpan(0, 5, 0);
}
}
My test function on the server:
[Invoke]
public void TestTimeout()
{
while (true)
{
Thread.Sleep(100); // after one full minute, I get the above exception
}
}
Could something else be timing out? I see the same problem on my local development machine as well as my production server running IIS7. I’m baffled as to what this could be. I don’t think the timeout values are being ignored since I no longer get the standard timeout exception. I just think there is another place that a timeout is happening.
Any ideas?
-Scott
This is just a thought, have you tried making your asp.net session timeout explicit, may be its on one minute..
Try putting this in the constructor of your proxy:
InnerChannel.OperationTimeout = new TimeSpan(24, 0, 0);

Silverlight 4 WCF RIA Service Timeout Problem

I have a Silverlight 4 usercontrol that calls a very long running WCF RIA service. As shown below, I am increasing the default timeout period.
_domainContext = new WindowsDashboardDomainContext();
// Increase timeout -- this can be a very long running query
((WebDomainClient<WindowsDashboardDomainContext.IWindowsDashboardDomainServiceContract>)
_domainContext.DomainClient).ChannelFactory.Endpoint.Binding.SendTimeout = new TimeSpan(99, 0, 0);
_domainContext.GetSections( "All", "All", "All" ).Completed += GetAllSectionsCompleted;
Unfortunately, it seems to ignore this timeout and still throws the timeout exception:
Error: Unhandled Error in Silverlight Application Load operation failed for query 'GetClicks'. An error occurred while executing the command definition. See the inner exception for details. Inner exception message: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
Why is this happening?
I answered the same question here: WCF ria service SP1 timeout expired
The answer:
I'll explain my context and I wish it will work for my. I'm sure about that.
First of all to call RIA services, and using some domain context, in my example:
EmployeeDomainContext context = new EmployeeDomainContext();
InvokeOperation<bool> invokeOperation = context.GenerateTMEAccessByEmployee(1, 'Bob');
invokeOperation.Completed += (s, x) =>
{....};
Nothing new until here. And with this I was facing every time that same timeout exception after 1 minute. I spend quite a lot of time trying to face how to change the timeout definition, I tried all possible changes in Web.config and nothing. The solution was:
Create a CustomEmployeeDomainContext, that is a partial class localizated in the same path of the generated code and this class use the hook method OnCreate to change the behavior of created domain context. In this class you should wrote:
public partial class EmployeeDomainContext : DomainContext
{
partial void OnCreated()
{
PropertyInfo channelFactoryProperty = this.DomainClient.GetType().GetProperty("ChannelFactory");
if (channelFactoryProperty == null)
{
throw new InvalidOperationException(
"There is no 'ChannelFactory' property on the DomainClient.");
}
ChannelFactory factory = (ChannelFactory)channelFactoryProperty.GetValue(this.DomainClient, null);
factory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 10, 0);
}
}
I looking forward for you feedback.
There are two possibilities that come to mind:
You have not configured your DomainService to serilalize enough objects. The default is very small. Try this tip I put in yesterday to increase the resultset allocation
Your data source may be timing out. In that case you need to increase the command timeout for LINQ to SQL, EF, or ADO.NET accordingly. This is the less likely cause, but one to consider.

Resources