Best way to handle long running tasks on the Server WCF + Rest - c#

We have a WCF + Rest service running on the host. I need to make a client call to the host that would initiate a long running task on the server (even up to 15 min), then check back once that process has finished to get the result. One solution is to have client checking the host every minute or so after the initial call - but that seems not very productive. Is there a way to expose some type of event through WCF so that client would be notified when the task completed on the server? What is the best approach for this type of scenario?
thanks

Kind of hard to answer without more application details.
But have a few alternatives (here are a few of them):
Use a message queue to initialize and get events when then task is
done (perhaps overkill)
If the client is a web client and you have the possibility ta have a web socket to the client you can notify the client that the task is done
Perhaps (not sure this is a good idea)
you can use duplex wcf contract (since you already use wcf), then the
service can invoke a method on the client interface when the task is
done
Or do a simple polling calls like you mention in your question.
Here are some more information regarding duplex contracts:
https://msdn.microsoft.com/en-us/library/ms731064%28v=vs.110%29.aspx

Related

WCF Duplex service VS Socket based on TCP

I'm working on a project including WCF server and remoting clients.Now the necessary functional part of the software need to push message from server to specified client.
I know that Socket can achieve this, but I want to use WCF Only. So I find document on WCF duplex service.Here is my idea:
I start a new thread which communicate with duplex service only once
and then wait for the callback from the server.(Keep the thread
alive and let the proxy opened for waiting the callback )
At the server side,I save all the clients' callbackInstance in a List,and once I want to invoke callback on the specified client,I will take the callbackInstance out from the List and invoke the callback method.
Question
Is my idea feasible?
If question one is yes,how to detect whether the client is still alive(Prevent from invoking the callback on a client-proxy which is closed. )
Is this something we can replace Socket in WCF Service?
Thanks a lot.
Everything is feasible ... It's all a question of what you know, what's involved, and how much time/money you have.
I haven't worked much with duplex WCF because I had to use one way in webservices, but another approach is using a framework like XSockets . It's version 4 is in beta ATM, but the developers are quite approachable and active, so if you have any issues, they'll be happy to work.
It'll give you real time communication in both direction with one to one or one to many, and might fit your use case ...

long running tasks under asmx service hosted on IIS

I have some legacy ASMX IIS hosted service. Client applications make subscribe or unsubscribe to the web service. Via some internal to the web service logic it needs to send messages to the subscribed applications periodically.
What is the best way to do the part of the long running task ? I understand opening Thread with long running task not a good idea to do under IIS.
ASMX services cannot do what you're asking for: they cannot just decide to send a message to the client. All they can do is respond if the client requests it.
You can hack around and come up with one method to start the long-running task, and another method to poll for the status of the task. This works, but it can be expensive.
The better model is to perform the long-running task in a separate Windows Service. Have that service host a simple WCF service which will only be used by the main service (the one that talks to the clients). The main (WCF) service would use a Duplex channel to communicate with the clients. That way, it can "call" the clients whenever there is news about one of the long-running tasks.
Usually in such cases when you don't have a way to push the result back, create an unique ID for the long running task and sent it back to the client, after that run the task and have a table in database or something else where you store the status of the task. The client will pull periodically the service to see the task' status by given ID. Once it finds the task is completed it will retrieve the result.
And is completely fine to have a thread running inside IIS doing its job.

How to make a call to WCF webservice with more than one client at the same time (in parallel)

I have a c# WCF web service which is a server and I do have 2 clients one is java client and another is c++ client. I want both the clients to run at the same time. The scenario I have and am unable to figure it out is:
My java client will be making a call to the WCF web service and the processing time might take around 10 mins, meanwhile I want my c++ client to make a call to the web service and the get the response back. But right now I am just able to make a call to web service using c++ client when the java client request is being processed. I am not getting the response back for c++ client request until java client request is completed.
Can any one please suggest me how to make this work parallel. Thanks in advance.
Any "normal" WCF service can most definitely handle more than one client request at any given time.
It all depends on your settings for InstanceContextMode:
PerSession means, each session gets a copy of the service class to handle a number of requests (from that same client)
PerCall means, each request gets a fresh copy of the service class to handle the request (and it's disposed again after handling the call)
Single means, you have a singleton - just one copy of your service class.
If you have a singleton - you need to ask yourself: why? By default, PerCall is the recommended setting, and that should easily support quite a few requests at once.
See Understanding Instance Context Mode for a more thorough explanation.
Use
[ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Multiple )]
attribute over your service class. More on this for example here:
http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and
This is peripheral to your question but have you considered asynchronous callbacks from the method that takes 10+ minutes to return, and then having the process run in a separate thread? It's not really good practice to have a service call waiting 10 minutes synchronously, and might solve your problem, although the service should allow for multiple callers at once anyway (our WCF service takes thousands of simultaneous requests).
When you call a WCF you have a choice in either calling it synchronously or asynchronously. A synchronous call waits for the response to send back to the caller in the same operation. In the caller it would look like "myresult = svc.DoSomething()". With an asynchronous call, the caller gives the service a function to call when it completes but does not wait for the response. The caller doesn't block while waiting for the response and goes about its business.
Your callback will take DoSomethingCompletedEventArgs:
void myCallback(object sender, DoSomethingCompletedEventArgs e)
{
var myResult = e.Result;
//then use the result however you would have before.
}
You register the callback function like an event handler:
svc.DoSomethingCompleted+=myCallback;
then
svc.DoSomethingAsync(). Note there is no returned value in that statement; The service would execute myCallBack when it completes and pass the result. (All WCF calls from Silverlight have to be asynchronous but for other clients this restriction isn't there).
Here's a codeproject article that demonstrates a slightly different way in detail.
http://www.codeproject.com/Articles/91528/How-to-Call-WCF-Services-Synchronously-and-Asynchr
This keeps the client from blocking during the 10+ minute process but doesn't really change the way the service itself functions.
Now the second part of what I was mentioning was firing off the 10+ minute process in a separate thread from inside the service. The service methods themselves should be very thin and just be calling functionality in other libraries. Functions that are going to take a long time should ideally be called in their own threads (say a backgroundworker, for which you register on the service side a callback when it completes) and have some sort of persistent system to keep track of their progress and any results that need to go back to the client. If it were me I would register the request for the process in a db and then update that db with its completion. The client would then periodically initiate a simple poll to see if the process was completed and get any results. You might be able to set up duplex binding to get notified when the process completes automatically but to be honest it's been a few years since I've done any duplex binding so I don't remember exactly how it works.
These topics are really too big for me to go into depth here. I would suggest researching multithreaded operations with the BackgroundWorker.

C# WCF return request to self hosting server

I am running WCF self hosting server. Connection is coming fine and I can process them.
But now for long connections we decided to break a connection, process request and send results back to self hosting server on client side.
How do I know which client should I send a request back? DO I need remember every client address? How do I know their address, should they provide back address as input parameter? Or maybe there are much easier, correct and elegant way to solve this common issue?
As cillierscharl already said, you could use callback contracts.
Links to give you a quick start:
WCF Essentials - What You Need To Know About One-Way Calls, Callbacks, And Events
WCF Callbacks – A quick introduction
Simple Example from Stack Overflow
Chat Example
WCF Duplex Reentrant Services
Best (beginners) article about WCF Callbacks
Stack Overflow: keeping a wcf callback channel open indefinitely / reconnecting from client if it faults
Synchronization Contexts in WCF
Advanced Stuff and things you should worry about:
Detecting Client disconnection
Reestablish Connection Management
Concurrency Mode and Instancing (Threading..) / Synchronization Contexts

wake up a service, communication with services

Some time ago i Wrote a service with a timer that make an action every n minutes. All was right. But now, I want to write a service that waits for a signal, message or something from a gui application for doing his job.
I want me process to sleep pacefull (not in a infinite loop sniffing something) until my winforms application tell him "Hey, do things and give me a ring when the work is done"
could someone give me staring point?
Thanks.
You can use Windows Communication Foundation to allow your client to communicate with your service, send it requests, and register to receive progress events from existing running jobs.
You need to use interprocess communication (IPC). For C#, this usually means either .NET remoting -- on older versions of .NET -- or Windows Communication Foundation (WCF) -- on newer versions of .NET.
Essentially, the client application connects to an interface implemented by the service, and can then call methods on it, as if it was in the same process.
If this is too complicated, you could use a named event object, which the service waits on, and the client sets.
Starting point:
Self-hosting WCF service
Any of the IPC mechanisms qualify to get this done. If your needs a simple, just message passing, consider either a named pipe (NamedPipeServerStream) or a socket. If they are elaborate, consider Remoting over an IPC channel or WCF.
Personally, I like named pipes for this. Just make sure the pipe name is prefixed by "Global\" so it is visible from the interactive desktop session. Encrypt the messages if security is a concern. Spin up a background thread in your service that makes a blocking call on the pipe stream to implement the message handling.
If the windows service is on the same machine, you could stop and start the service? or call a webservice that stops/starts a service on a another machine?
If you did have a service that polls (or "sniffs") for something to do , this could be a very small and basic call to a database to check for something that will trigger the actual work?

Categories

Resources