WCF Service call another service in background - wcf

I want to call a web service from another web service in a non-blocking way. I've implemented this by using BackgroundWorker. But, I'm not sure whether this is the best way to do.
Scenario:
I call a web service Service_A which performs certain task & has to inform another web service Service_B about the changes made. I call the Service_B's one-way function NotifyUpdates for handling the updates. Service_A doesn't waits for Service_B's response & continues with its task. The response from the Service_B is logged in the background.
My question is, what is the best way to do it?
Thanks.

BackgroundWorker is purposed for UI use, and I don't think it's the best way to use it here.
If you are using .Net 4 better to use Task
var t = Task.Factory.StartNew(() => DoServiceBCall());
If not,use ThreadPool.QueueUserWorkItem or Thread
ThreadPool.QueueUserWorkItem(new WaitCallback(DoServiceBCall));
Hope this helps

First of all, based on your scenario, if call to Service B is one way, Service A will not receive any response from Service-B except Http Status code (if call to service-B is on Http).
I'd call Service-B asynchronously to keep the things and code simple.
HTH,
Amit

Related

Long calculation in a wcf restful service

I have a WCF restful service and it works correctly, the problem is that the service expose a method "Calculate" and it may take several minutes to complete the calculation, and since REST is a stateless method, I'm running out of ideas !
should I maintain the session ?
how can I do a callback ?
10 minutes waiting for a response in a website is not convenient, but I have to find a solution.
PS: the service MUST be restful, and I cant reduce the calculation time.
I asked about your clients because if they were .Net only, you could implement the async programming model, but since they aren't...
You can do something like in this post - WCF Rest Asynchronous Calling Methods
Basically your method will spawn an additional thread to do the actual calculation work, and return some sort of token to the calling client immediately in the main thread. The client can then use this token in a polling method to check if the calculation is complete.
You can create a one-way WebMethod to submit the intial calculation request. Inside your calculation code, you need to update a database table or similiar with progress, either percentage or completion.
You will then need to create an additional 'Polling' method that you can use to check the status, using the previous table.
When your calculation method marks it as complete, you can then call a final 'GetResults' method which will do just that.
We do something similiar for large file imports that are submitted via web services and it works very well.
Some info;
http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapdocumentmethodattribute.oneway(v=vs.71).aspx

Design for a special WCF service

I need to implement a WCF service which in turn calls a third party web service for some XML result.The client calls come from windows WF apps & will be on separate processes.But for client calls coming from the same parentID, there should be only one call per ParentID, i will explain,
MainID1\SubID1 & MainID1\SubID1 on different processes calls the WCF service for result & if MainID1\SubID1 was the first to make the call, MainID1\SubID2 should wait until the first call is completed.The idea is to prevent unnecessary call to the third party web service, if we get the expected results already from the first call.
But if there are MainID2\SubID1,MainID2\SubID2,MainID2\SubID3 calls, that should be served by a different instance of the WCF service.
In short:
Related requests should be processed sequentially by one instance of WCF service
Unrelated requests should be processed by separate instance
Sorry, if haven't made myself clear, not at the liberty to use the actual business terms(which might have helped to define related & unrelated clients better).
Is this really possible?
Yes, you can do this, but it will not be trivial. Basically you need another component between your WCF Web Service and the 3rd Party service which handles the throttling/locking behavior which you describe. That component needs to create a object for each unique combination and then use that as a lock guard around the outbound call.
Realize that this is clearly multi-threaded development, making it hard to test, and prone to errors if you're not experienced with the ideas around it. You'll want to ensure you're doing double-checked locking whenever you take out a lock.

One way web service still returns a response

I aplogise if my terminology is inaccurate, still deep in learning.
I am creating a web service to act as an intermediary between Silverlight and XMPP. To start all of this I have created a web service call to enable me to ask the server to log on on my behalf and the idea is that the server will log on and then push back to my client once complete.
I have based the idea on the code form this site: http://weblogs.asp.net/dwahlin/archive/2011/02/06/syncing-data-with-a-server-using-silverlight-and-http-polling-duplex.aspx
Now the problem I have is that the Register call I have created will use an asynchronous call to log into XMPP. But the register call itself is also asychronous. So I don't know the best way for a web service call to wait for another service's async call
What I thought of doing was making the Register a one way call with the idea being that my server will log into XMPP then push the client once logged in (or fileld etc)
[OperationContract(IsOneWay = true)]
void Register(string name, string password, string nickname);
But when I imported the Service Reference the class generated appears to have a RegisterCompleted() call which debug shows is invoked. But I thought one-way meant no response is called so why is it?
One Way means No Response Data. Internet protocols are a request-response model where there is an acknowledgement for the receipt of the request. Your Register service returns no data (void) so RegisterCompleted really did "completed accepting three string parameters and returned no data".
This is a good thing - now you know if you had a problem starting the registration or everything is good so business as usual until you hear back from the server. You don't know yet if you're actually registered yet so that's why your client continues to Poll the server until the server responds - good or bad.
His previous article references an good MSDN example on using the PollingDuplexHttpBinding.

Can WCF be auto scheduled?

I have below requirements:
(1) Perform 'action A' when user requests for it.
(2) We also want to perform the same 'Action A' twice in a day even if users don't request for it.
I have a WCF web service which has method XYZ that performs action A. The method XYZ will be called when user requests for it.
Now question is, can I schedule this action without creating window service (which can host this service) or creating proxy?
Is there a way to perform an action by user request and schedule that same action, using only one application?
No, WCF cannot be auto-scheduled. You need to implement a Scheduled Task (see Scheduling jobs on windows), a Windows Service with a timer (which you've said you don't want to do, if I understand correctly) or some other application with a timer.
You could start a thread as per the other answer but this relies on your service calling itself - I'd prefer to call it externally, from another process.
A scheduled task can run an executable. You could write a console application that calls your WCF service, logs any result (if necessary) and then completes.
I normally prefer to implement this type of timer through a Windows Service, simply because the Windows Service can be monitored, can log, and can auto-start / auto-restart - install it and it 'just works'. If I didn't want to use a Windows Service then I'd schedule a task.
I typically do this by just calling the WCF service method from some kind of task scheduler. In a really simple form, you could just spawn a Thread from your service, that runs the WCF method periodically. Again this isnt the best solution, but its easiest to demonstrate. You could use some other scheduler library to do this too...
[ServiceContract]
public class SomeClass
{
[ServiceOperation]
public void SomeServiceMethod() { ... }
Then somewhere in the application startup:
Thread t = new Thread(new ThreadStart(CallService));
t.Start();
...
// this will call the WCF service method once every hour
public void CallService()
{
Thread.Sleep(3600000); // sleep 1 hour
new SomeClass().SomeServiceMethod();
}
This is one way to do it, although not the best way, but basically you can just call the WCF service method just like any other method in the application.

Force a client to call a method on the service?

I'm wondering if there's any way to force a client to call a specific method on a duplex WCF service. My situation is this, my service implementation is going to keep a collection of subscribers. The problem with this approach is, what if the client doesn't call Subscribe()? I was thinking that in my client interface, I'd have a method called Subscribe, but that doesn't get me anywhere since the code to actually call the service can still be left out of the implementation. Is this possible?
Thanks!
Duplex WCF service uses WCF session so you can mark your Subscribe method with:
[OperationContract(IsInitiating=true)]
void Subscribe();
All other methods will have IsInitiating=false and because of that Subscribe method will have to be the first method called to start a new session. You can also have special method with IsTerminating=true to close the session.