I am new to WCF web services. My requirement is to create a WCF service which is a wrapper for third-party COM dll object.
Let's assume that the dll takes 5 sec to calculate one particular input.
When I created the service and tested it (using the WCF test client) the scenario I see that I am not able to send 2nd request until first request is completed.
So I was thinking to start a new thread for consuming the com functionality and call a callback function once done. I want to send the response and end request in this callback function.
This is for every request that hits the WCF service.
I have tested this, but problem is I am getting the response without completing the request.
I want current thread to wait until the calculations are done and also accept other requests in parallel
Can you please let me know how I can fix this considering the performance?
My service will be consumed by multiple SAP Portals clients via SAP PI
The concurrencymode for service can be set applying [ServiceBehavior] attribute on Service Class implementing ServiceContract.
http://msdn.microsoft.com/en-us/library/system.servicemodel.concurrencymode(v=vs.110).aspx
However, in your situation where you access a COM component in service operation, I'd first check the Threading model for COM component i.e. does it implement Apartment (STA) or MTA. If COM component implements Apartment threading model, COM call invocation will be serialized. Thus, changing WCF ConcurrencyMode will not have any impact.
HTH,
Amit Bhatia
Related
This is a best practices question.
Per this best practices article and per MSDN, the OrganizationServiceProxy is not thread safe.
If you have a multi threaded client application in which you are creating an instance of an
OrganizationServiceContext (on a per thread basis), the constructor of which accepts an
IOrganizationService instance and you pass in a global instance of the OrganizationServiceProxy
(i.e a static instance allocated once at the "process level"), will this cause threading issues and/or if the OrganizationServiceProxy instance faults, will it affect operations that the threads try to perform on their own "local" instance of the OrganizationServiceContext?
My belief is that it will, and that an OrganizationServiceProxy instance needs to be created on a "per thread" basis and that each OrganizationServiceContext in a multi threaded application would need its own corresponding OrganizationServiceProxy instance.
I'm posting this to get confirmation of the above.
Also, the article indicates
The service proxy class performs the metadata download and user authentication by using the following class methods
IServiceManagement<IOrganizationService> orgServiceManagement =
ServiceConfigurationFactory.CreateManagement<IOrganizationService>(
new Uri(organizationUrl))
AuthenticationCredentials authCredentials = orgServiceManagement.Authenticate(credentials)
By caching the service management and authenticated credential objects, your application can more efficiently construct the service proxy objects more than one time per application session
If I try to execute the above API calls manually, in Active directory authentication mode, the authCredentials.SecurityTokenResponse is null as indicated by MSDN
Is there a way to perform the authentication just once for AD mode and pass an authenticated SecurityTokenResponse to a newly created OrganizationServiceProxy via the following constructor?
OrganizationServiceProxy (IServiceConfiguration, SecurityTokenResponse)
so that you don't have to take the authentication and metadata download hit on a "per thread basis" when constructing the OrganizationServiceProxy instance per thread and just take the hit once?
Yes, you will definitely have issue if you attempt multi-threaded operations on a single IOrganization service.
We have two basic multi-threaded CRM applications: batch processors, and another web app. For the batch programs I've found it works better to only have 10 different threads, and to batch up the work among the 10 different threads. So if you're inserting 100,000 records, split them into 10 batches of 10,000, a single organization service for each thread.
We also have a website that does a lot of CRM interactions so there is no real way to batch the requests, so we created a CRM connection pool to reuse any open, already authenticated connections.
Of course this won't work at all if you're not using some system service account.
I have a COM object that creates an instance of a WCF service and passes a handle to itself as a callback. The COM object is marked/initialized as MTA.
The problem being every instance of the WCF service that makes a call to the callback occurs on the same thread, so they are being processed one at a time which is causing session timeouts under heavy load. The WCF service is session-based, and I am not sure if that makes any difference.
You could decorate the callback implementation with the CallbackBehavior attribute and set ConcurrencyMode to ConcurrencyMode.Multiple. The default setting is ConcurrencyMode.Single which restricts to one service callback at a time. Of course if you do that you must ensure your callback implementation is thread safe.
I've seen a project lately using a background worker to make some operations (get data from other web services) and throw the data using events to the client. This project is a WCF service and consume by an ASP.NET web site by another class library as WCF client role and throwing in turn events to the application. This all multithreaded series made me curious to examine. I've seen that this is a basicHttpBinding binding and the only behavior to the service is the UseSynchronizationContext=false where I found out that they added it after unexplained exception which is normal :)
Now I'm asking about the default ConcurrencyMode for the basicHttpBinding. Shouldn't they make it Reentrant or this is the default behavior?
Is this scenario will continue failing cause they already have an unexplained reference not set to an instance of an object if the WCF service is down from the client?
I believe using multithread operations in a WCF service consume by ASP.NET project which relies on IIS handling is bad cause the page could be sent to the client before the WCF service return data to the client class library and append these to the page.
Can you discuss the above and explain your thoughts?
Shouldn't be better when you need such an asynchronous programming style to inform WCF comsumers to notify after long operation using CallbackContracts and embedded WCF technologies, rather multithreading operations?
Need clarification to correct the design and have some proves that this is a bad service architecture, if it is for real, which I suspect!
Thank you.
It is not inherently bad architecture, but it sounds like it does create a number of possible pitfalls.
The WCF client library is leaving all the coordination up to the ASP.NET application. If the ASP.NET app isn't checking that a call to the WCF service has been completed, then it risks using variables before they have been set with values from the service, and other such race conditions unless explicitly setting up some manner of coordinating the initial call against the completion events.
My recommendation would be to rewrite the WCF client asynchronous methods to return Task objects, from the System.Threading.Tasks namespace (MSDN reference). In this way you can spin off the background processing calling the WCF service, and use the Result property of the Task to ensure the service has completed.
An example:
protected void Page_Load(object sender, EventArgs e)
{
Task<string> t = Task<string>.Factory.StartNew(() =>
{
return MyWcfClientClass.StaticAsyncMethod(MyArguments);
}
/* other control initialization stuff here, while the task
and WCF call continue processing in background */
/* Calling Result causes the thread to wait for the task to
complete as necessary, to ensure we have our correct value */
MyLabel1.Text = t.Result;
}
We have created a WCF RESTful service for a WPF(UI) Application. The UI sends a request to the WCF Service which then invokes a suitable method in BLL, which in turn invokes a method in DAL. All these layers have been separated using IOC/DI.
Now, for a new feature, we want that when a new object of a certain type is added to the database, it should go through 3 steps which would be performed in a separate thread.
That is, if service sends a request to BLL to add a new object OBJ to the database, the BLL should save the object into database through the DAL and then initiate a new thread to perform a some actions upon the object without blocking the WCF Request.
But whenever we try to do so by starting a new thread in the BLL, the application crashes. It is so because the 'InRequestScope' object of the database context has been disposed and the thread cannot update the database. Also the WCF request does not ends until the thread is completed, although the return value has been provided and the BLL method has completed execution.
Any help would be much valued.
I have figured out the solution and explanation for this behavior. Turns out to be a rather silly one.
Since I was creating a thread from the BLL (with IsBackground = true;), the parent thread (originated by the service request) was waiting for this thread to end. And when both the threads ended, the response was sent back to the client. And the solution, well, use a BackgroundWorker instead, no rocket science, just common sense.
And for the disposing of context, since the objects were InRequestScope, and the request had ended. So every time a Repository required a UnitOfWork (uow/context), it would generate a new context and end it as soon as the database request was complete. And the solution would be, create a uow instance, store in a variable, pass it to the repository required to be used, and force all repositories to use the same uow instance than creating a new one for itself.
This seem more of a client-side concern than a service-side concern. Why not have the client make asynchronous requests to WCF service since this automatically provides multi-threaded access to the service.
The built-in System.Net.WebClient (since you're access a webHttpBinding or WCF Web API endpoint) can be used asynchronously. This blog post gives a quick overview of how it is done. Although this MSDN article seems to apply to file I/O, about three quarters down, there is a detailed explanation on coding asynchronous WebClient usage.
I have a Java servlet that acts as a facade to other webservices deployed on the same Tomcat instance. My wrapper servlet creates N more threads, each which invokes a webservice, collates the response and sends it back to the client. The webservices are deployed all on the same Tomcat instance as different applications.
I am seeing thread blocking on this facade wrapper service after a few hours of deployment which brings down the Tomcat instance. All blocked threads are endpoints to this facade webservice (like http://domain/appContext/facadeService)
Is there a way to control such thread-blocking, due to starvation of available threads that actually do the processing? What are the best practices to prevent such deadlocks?
The common solution to this problem is to use the Executor framework. You need to express your web service call as Callable and pass it to the executor either as it stands, or as a Collection<Callable> (see the Javadoc for complete list of options).
You have two choices to control the time. First is to use parameters of an appropriate method of the Executor class where you specify the max web service timeout. Another option is to do get the result (which is expressed as Future<T>) and use .get(long, TimeUnit) to specify the maximum amount of time you can wait for a result.