Running long process in WCF Service - c#

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.

Related

How to update a windows service without having to uninstall service from service list

So I'm trying to figure out how to stop a service, update the code and then start the service again. I'm stopping the service with this:
sc stop "name of service"
When I update the code (override the exe file and additional reference files) and try to restart the service like this--sc start "name of service"--it tells me this:
[SC] StartService FAILED 1053:
The service did not respond to the start or control request in a timely fashion.
If I put the original files back and try to restart the service it starts fine.
Do you have any idea what I'm doing wrong?

Asynchronous calls within a WCF Service

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?

Duplicate windows service, different name and location - will not start

I have a windows service that has it's name set by an app.config.
I set the name as follows:
The ServiceBase.SerivceName is set on the Service class constructor (I have removed the setting of the ServiceName in the Service.Designer):
ServiceName = ConfigurationManager.AppSettings.Get("ServiceName");
The ServiceInstaller sets the DisplayName and ServiceName like this:
ServiceInstaller.DisplayName = config.AppSettings.Settings["ServiceName"].Value;
ServiceInstaller.ServiceName = ServiceInstaller.DisplayName;
All works as expected, so the service is installed fine alongside a duplicate service.
They have different names and different locations.
The appear as seperate entries in the Services list.
But I can only start one service at a time. The error I get on trying to start the second service is the unhelpful:
The service is not responding to the control function.
There are 2 System Events that get logged when trying to run:
A timeout was reached (30000 milliseconds) while waiting for the Blah Service service to connect.
The Blah Service service failed to start due to the following error:
The service did not respond to the start or control request in a timely fashion.
Any help gratefully received.
Thanks.
In the absence of sufficent info to offer an answer to the problem at hand, I suggest using http://topshelf-project.com/ - it makes installing, configuring and debugging windows services in .NET a breeze.

How to asynchronously wait for response from an external application that intercepts printer output

I have designed a system that is made up of 3 separate applications:
Web Application
WCF Service application that receives requests from the web app, does the appropriate action and prints the result using the SendKeys class SendKeys.SendWait("^p"); (this send a Ctrl + P command that prints whats on the screen).
Console application that intercepts printer output (virtual printer via redmon) via the Console.In (as suggested here
The WCF Service app and Web application can communicate easily, but there is no direct communication between the service app and console application. The console app only starts when there is a printer job and the WCF app doesn't know the result of the print job.
Is there a way to make the WCF Service app recieve feedback from the printed job (whether it was ok or not), so it can send appropriate response back to the web application, without doing Thread.Sleep() each second until the printer app finishes printing and saves the result in a file or database?
Is there a way i could pause the thread in the WCF service app, and resume it (whilst sending information back) from the printer console application when the printing process is done?
Edit:
I managed to find a solution from Richard Blewett's suggestions. The solution would make the WCF service app wait untill the print job is finnished, but it will cause the WCF app to be limited to only making one print job at a time.
I create an EventWaitHandle with some key in the WCF app like this:
EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.ManualReset, "unique-key");
WaitHandle.WaitAny(new WaitHandle[] { ewh });
And i can return to the thread from the Console app like this:
EventWaitHandle ewh = EventWaitHandle.OpenExisting("unique-key");
ewh.Set();
With Richard's solution this will not be the case, and multiple WCF service calls can be done simultaneously.
Assuming there is a unique identifier for the print job then the console app could call the WCF service to say the print job is either completed OK or failed.
The WCF service would either have to block until the completion call came in (waiting on say a ManualResetEventSlim) or you would have to write the service as an async service so the request thread could be returned to the pool while the print job was in progress.
The reason you need a unique identifier for the print job is you will have to hold a data structure in memory in the service mapping unique id to event so you can signal the correct waiting request when its job is complete
When the WCF service creates a print job it puts an entry in, say, a ConcurrentDictionary mapping printJobId to a non signalled ManualResetEventSlim (one for each print job). It then waits for the event to signal.
Now when the print job completes, the console app in turn calls the WCF service passing its printJobId. This operation does to the dictionary, grabs the event and signals it. The original call now wakes up knowing that the print job is complete.
The status of the print job could also be passed via this dictionary data structure so you would have something like
class PrintJob
{
public PrintJob()
{
Event = new ManualResetEventSlim();
}
public ManualResetEventSlim Event {get; private set;}
public int Status{ get; set;}
}
and the dictionary would map the printJobId to one of these for each print job. The console app called operation would set the status to the outcome of the print job

webservice timeout c#

I have a c# application and I want to fire off a webservice but I dont care about the response and I also dont care if it fails. At the moment i fire of the service async but i am getting an error when the call fails.
Is there anyway I can configure the app/webservice to stop it failing without rapping try catches around them (basiclly fire and forget)?
Thanks
Sp
Here is one idea:
Write your web service do that it returns 'success' right away, then fires off an async process that does the work.
You can also do this by creating a queue or something, where another process watches the queue and performs the work. Then the web service's only job, then, is to add an entry to the queue.

Categories

Resources