I am trying to write code that imports a bunch of data as quickly and reliably as possible. Using threading I have been able to speed up the import code I wrote significantly on my local machine, but when I run it on our remote server it seems to have some WCF problems...
I have two WCF Service implementations: Service1 and Service2.
Basically this is the workflow:
Parallel.ForEach(objectData.Tables[0].Rows.Cast<DataRow>(), dataRow =>
{
...
Service1.ImportObjectFirstPart(ObjectToEnter);
...
Service2.ImportObjectSecondPart(ObjectToEnter);
}
Service1 call takes about 3 seconds, and service2 takes about 7 seconds both remotely and locally. However on my local machine, calls to service2 start after about 20 service1 calls. On the server, almost every service1 call finished before the first service2 call started. (Both services are implemented as PerCall).
The code to call the services uses 99% CPU as expected for awhile then slows to a crawl, then I have to exit it myself. Any idea what could be going wrong?
Thanks,
Have you tried
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
you can read the details here
http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.concurrencymode.aspx
The default is single so you should expect the behavior you are getting is pretty justified.
Related
I have a WCF service which configure to be one way and below Service configuration:
[Service Behaviour(InstanceContextMode = InstanceContextMode.PerCall)]
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
This is what the service does:-
First sync files from source control then parse the files next reconstruct contents in another format and rewrite the files out. Finally check into source control again.
It works fine when only 1 call being invoke. But when there are multiple calls invoke at the same time, they will all stuck at the sync part example caller A contains file but caller B no file found. If this happen subsequent call will failed until Application pool get restarted.
There is no error return from the service is just got lost somewhere and process stuck in the middle.
Is it advisable to implement a long process like above with syncing files from source control in wcf service or invoking an exe each time service call or should I put it in queue mechanism and let the queue to manage the processing?
Thanks.
I will be deploying my first application based on WCF and would like to know the best way to deploy. Here is my architecture. Please see the attached image.
We have a WCF written using 4.0 framework and has 3 methods. A front end ASP.NET website (www.site.com) calls the WCF to save data as well as read data. In figure method1 is saving to data and method2 and 3 are for reading the data from SQL server 2008 R2 database.
In my ASP.Net webstie...
I am calling the Method1 and closing the connection...like this..
ServiceClient client = new ServiceClient();
client.Method1(data to be saved)
client.close();
I am calling method 2 and 3 as follows
ServiceClient client = new ServiceClient();
dropDown1list.datasource = client.Method2()
dropDown2list.datasource = client.Method3()
client.close();
Multiple users could be using the website at the same time to submit the data. Considering this architecture..what would be the best way to deploy the WCF so that it could handle multiple users at same time?. I read the article http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and and http://www.codeproject.com/Articles/86007/ways-to-do-WCF-instance-management-Per-call-Per.
I now believe I need to have my WCF service as
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple , InstanceContextMode = InstanceContextMode.PerCall )]
public class Service : IService
{
public bool Method1(data to be saved)
{
}
public List<string> Method2()
{
}
public List<string> Method2()
{
}
}
Am I right ?. Any suggestions ?.
Just answered a similar question yesterday. Based on your description and the picture, I don't see a need to change your architecture. If you're using one of the main WCF bindings (webHttpBinding, wsHttpBinding or BasicHTTPBinding), the service you deploy should easily be able handle dozens of concurrent users, all saving and reading at the same time.
Each client request will generate its own connection and web service objects, each of which can communicate concurrently with your database, whether that request is to read data or write data. When the response is sent back to the client, your WCF service will destroy the objects and clean up the memory for you as long as you're not doing something strange.
I've spent the last two years working on WCF web services on and industrial scale. Lately I've been working on a load testing / benchmarking project that spins up hundreds of concurrent users, each of which is slamming our WCF test server with XML artifacts that get loaded into the database. We've managed to load up to 160 packages (about 110kb - each per client) per second. WCF is not perfect, but it's quick, clean and scales really well.
My experience has been that your database will be your bottleneck, not your WCF web service. If your client wants to scale this archtecture up to an Amazon size web service, then you bring in an F5 load balancer and scale it up that way.
We have a situation where we need to execute some long running code in the InitializeService method of a Data Service. Currently the first call to the data service fires off the code, but does not receive a response until the long running code has finished. The client is not required to wait for this action to complete. I have attempted to use a new thread to execute the code, however with the code being run we are replacing some files on the server which seems to kill the thread and causes it to bomb out. If I don't have it in a thread it runs fine, but the InitializeService method takes a long time to complete.
Are there any other ways to run this code asynchronously (was thinking maybe there is a way to call another method in the same fashion that a client would)?
Thanks in advance.
All WCF communication is basically Asynchronous. Each call spins up its own thread on the host and the processing starts. The problem you're running into, like many of us, is that the client times out before the host is finished with the work, and there's no easy way around that beyond setting the timeout to some ridiculous amount of time.
It's better to split your processing up into two or more parts, starting the intialization process and finishing the initialization process in separate steps, like this:
One option you could try a duplexed WCF service with a call back function to the client. In other words, client "A" calls the host and starts the initialization routine, but the host immediately sends back the client a value of IntializationStart=True so that the client isn't left waiting for the timeout. Then, when the host has finished compiling the files, it calls the client (which has its own listener) and sends a messages that the initialization is ready. Then the client calls the host and downloads the processed files.
This will works well PC-to-server, or server-to-server.
Another option could work this way: client "A" contacts host and host starts the Initialization routine, again sending back IntializationStarted=True. The host sets an internal (DB) value of FilesReady=False for client "A" until all the files are finished. At that point, host sets its internal value of FilesReady=True. Meanwhile, the client is on a timer, polling the host every minute until it finally receives that FilesReady=True, then it downloads the waiting files.
If you're talking about an iPhone-to-server or Android-to-server, then this is a better route.
You follow?
I have a self hosted WCF service, using basic http binding. I am finding that calls made to the wcf service, accessing functions exposed by the WCF, take much much longer to complete (internally) than when using the functions directly (from the wcf service).
So to clarify, I am not talking about taking longer "over" the wcf call. Once the internal exposed functions behind the WCF are run, they, in their own processing, take much longer to do their work and return something back to the wcf service, for sending to the client, than when I access those same functions directly from a form in my hosted wcf app.
I have added extensive logging, logging start and stop time for all functions, and it seems to be consistent. The same functions, when activated through WCF, seems as if they are run at a much lower "priority" than when calling them bypassing the WCF interface.
Taking this into account, I am pretty sure this started sticking its head out after I decorated my main wcf class with the following, due to my UI thread locking up:
<ServiceBehavior(useSynchronizationContext:=False)>
Are the threads created due to the above decoration, running at a lower priority?
Direct Call from form in WCF hosted App: 5 seconds
Call Through WCF Interface: 20-30 seconds (Excluding time over the wire)
The physical return from the WCF service itself, once the internal functions are complete, is quite quick.
I do quite a lot of "work" once the internal functions are reached.
Any ideas?
Thanks
Basic WCF Service Code:
Dim myservicehost As ServiceHost
Dim myServiceAddress As New Uri("http://" & LocalIpAddress & ":" & tcp_port & "/" & servicename)
myservicehost = New ServiceHost(GetType(myWCFFunctions), myServiceAddress)
' Enable metadata publishing.
Dim smb As New ServiceMetadataBehavior()
smb.HttpGetEnabled = True
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15
myservicehost.Description.Behaviors.Add(smb)
myservicehost.Open()
I could not get this solved, and reverted back to my previous implementation.
I have a client / server type of application and I'd like the server object to create his own host. It looks something like this:
public class Server : IServer {
private ServiceHost m_Host;
public Server() {
m_Host = new ServiceHost(this);
m_Host.Open();
}
}
It seems to work fine when there are few message transfers occurring. But when it starts to speed up (my application requires that data is transfered every 50 ms), the server hangs and and the transfers stop after a few seconds without throwing an exception.
So, is it possible for an object to create his own host? Or do I really have to create it in the main() or do something else?
EDIT: I think the problem in this case is that I want the object that implements the service itself to create his own ServiceHost.
There's nothing really stopping any object to create an instance of ServiceHost.
The big question then is - can you guarantee that your object containing the service host is "alive"? Or was it garbage collected by any chance?
We use Windows (NT) Services to host our own custom service host classes to provide around-the-clock availability for WCF services - works just fine.
Marc
To be a WCF service it simply needs to implement the service contract. There's nothing to stop you adding more methods to open and close an instance of itself as a service.
Check out the ServiceBehaviorAttribute which allows you to specify how your service ... behaves. ;) The ConcurrencyMode property defined the support for multithreading and defaults to single threaded mode, and the InstanceContextMode defines if the service object is per session, per call or singleton.
Quote from ConcurrencyMode:
Setting ConcurrencyMode to Single instructs the system to restrict instances of the service to one thread of execution at a time, which frees you from dealing with threading issues. A value of Multiple means that service objects can be executed by multiple threads at any one time. In this case, you must ensure thread safety.
Quote from InstanceContextMode:
If the InstanceContextMode value is set to Single the result is that your service can only process one message at a time unless you also set the ConcurrencyMode value to Multiple.
We could really use some code examples of your service to further debug the behavior you're describing. For example, is your service object expensive to construct (assuming non singleton implementation), or do the operation slow down? Do you know where the time is spent, is it code, or could it as well be some firewall that limits connection? What protocol do you use?