I am currently working at a personal project in c#.
The client is in WPF and connects with a WCF service that saves some data from web (the database is mapped with entity).
So, my problem is at my wcf service.
I am not very pro in c# or multitasking, but I need some guidance before going forward.
The scenario sounds like this:
Save from client to WCF.
WCF gets the request and initiates the function.
Returns a message to client that data will be processed and starts a task that:
Downloads data from internet
Saves it.
The problem is that the data that I save has an unique id and I check before saving so that data doesn't exists in database.
But, if 2 clients calls simultaneously save function with same data, there will be two tasks that saves info with same id. The id's are the imdbId which are unique.
My idea is that I make a list of tasks and I start a "watcher" that watches over that list and when a client makes a save call, I add the task for saving in the list.
Therefore, the task are ran iterative from the list.
How can I achieve this idea in c#? Data types? Tasks? ThreadPool?
Also, I think that the list must be singleton.
Related
I have two servers(and could be more later) with a WCF service, both behind a load balancer. The client application, in multiple IS servers(also loadbalanced), call the WCF to do some action, lets say a Save.
The same data, lets say Client information, could be opened by several users at same time.
The Save action can be, then, be executed from several users at the same time, and the call will go to different WCF servers.
I want that when a user call Save from UI, and there is already a Save in progress from another UI over the same Client data, then the second user be alerted about it.
For that, all WCF instances should know about actions been executed in other instances.
How can I synchronize data status between all WCF server instances then ?
I dont want to share the data, just some status of the data(opened, save in progress, something like that)
please advice, thanks,
I'm working with c#/.NET4
Added: WCF is actually hosted inside a windows service.
The problem you are having is one of resource management.
You are trying to resolve a way how you can get your service clients to somehow all know about what open handles each other have on internal state within your service, and then force them to orchestrate in order to handle this.
Pushing this responsibility onto your clients is going to make things much more complex in the long run. Ideally clients should be able to call your service in as straightforward manner as possible, without having to know about any other clients who may be using the service. At most clients should be expected to retry if their call was unsuccessful.
Normally you would handle these situations by using locking - the clients could all commit changes simultaneously and all but one will have to retry based on some exception raised or specific response sent back (perhaps including the updated ClientInformation object), depending on how you handle it.
If you absolutely have to implement this notifications stuff, then you could look at using the WCF duplex bindings, whereby your service exposes a callback contract which allow clients to register a handler for notification which can be used to send notifications to all clients on a different channel to the one the request was made on. These however, are complex at best to set up and do not scale particularly well.
EDIT
In response to your comment, the other half of your question was about sharing state across load balanced service endpoints.
Load balancing wcf is just like load balancing websites - if you need to share state across them you must configure some backing data store which all services have access to.
In your case the obvious place would be the database. You just need to make sure that concurrency/deadlock related problems are caught and handled in your service code (using something like NHibernate to persist the data can help with this). I just don't see that you have a real problem here.
I have a WCF service in which I have long running methods like get and process some kind of data and then return it to client. I have tried to use contracts similar to following
Task<string> ServiceMethod(string message);
The problem is if I want to return the same data to multiple clients from the service then how can I do it (How do I get and store information about clients who are requesting data).
Also if I need to call a background worker from the above method then how do I process in the runworker_completed and return the result to the above.
Additional info
The returning of same data to multiple clients is only in case the clients request the same data but since it takes time to get and process it so whenever it is available I want to return to all the clients who have requested it.
if I understand your question correctly, you want the service to callback clients when it finishes a long running process that generates data. As you have to take care of multiple clients, I would recommend that you use Duplex WCF. A duplex service contract provides for calling back a method on invoking client. The following code project link is good example for Duplex and has a lot more details
http://www.codeproject.com/Articles/491844/A-Beginners-Guide-to-Duplex-WCF
Note that you should have your own logic for maintaining the list of callback channels
I have stored a cache of Task in the service with the keys requested. Whenever the task for that key is completed I send back tasks to all the clients which had requested the same key.
Also for already existing functions with event based completion I have used TaskCompletionSource and stored it in the cache and again using it to send async response.
Writing a client application that sends images to a server via a webservice. As the amount of data can be large i have a need for a progressbar that shows the progress. Can someone point me in the right direction on how to hook into the webservice so i can show the progress in the client.
When you have to send a lot of data and you don't have threads, an easy way to get a progress bar is splitting the data in smaller chunks, and send them one by one, that way you know the progress, of course, the service must be able to join the pieces together afterwards.
One idea would be the following:
Call the web service as normal.
Web service returns immediately providing a unique identifier (e.g., id or GUID).
The web service continues to process the request (asynchronously). Occasionally it will update a status location (e.g., DB field) with progress update.
The client calls a second web service providing the identifier as a parameter. This second web service then provides the current status. One of the status messages is 'complete'.
The client continues to poll for status updates until the 'complete' message is returned.
Upon receiving the 'complete' message, the client is calling a third web service to retrieve the final result (providing the identifier).
One of the possible approaches involves splitting the file into smaller chunks, uploading them chunk-by-chunk with separate service calls which allows you to show the progress.
A small drawback is that you have to put all the chunks into the big file at the server side when the last one gets there.
I have a tcpclient that connects to a backend system sending xml queries and receiving xml responses.
The backend requires that the client logon and set some environment settings before any querying can take place. This is an expensive operation so it makes sense to create the tcpclient and keep it open for repeated queries.
The backend I'm told is optimised for handling many connections and for performance reasons I'd like to have numerous tcpclients connecting.
The queries are in the form of a list which contains thousands of items.
My question is how best to create a group of reusable connected tcpclients so I can execute a number of simultaneous requests from the list (say 10 at a time), what pattern would suit this scenario and are there any examples I can learn best practice from?
Currently it just executes them one by one using a single service which encapsulates the connection and logon process.
QueryService service = new QueryService(server, port, user, pass, params, app);
foreach(var item in queries)
{
service.ExecuteRequest(item);
}
service.Disconnect();
What you need is a thread pool or Object pool pattern. Basically, you can create a pool of Service objects and then when any element (function or object) of client application need to access the service - it can just refers to the service object based on some criteria.
To make this successful, you must have a request should be state-less so that when an arbitrary service object is selected for making a request to some server - the history should not create a problem.
I'm looking to create a web service and accompanying web app that uses an async web service call. I've seen plenty of suggestions on how to do async calls but none seem to fit exactly what i'm trying to do or are using a really outdated tech. I'm trying to do this in ASP.net 3.5 (VS2008)
What i need to do is:
the webpage needs to submit a request to the service
the page then needs to poll the service every 5 seconds or so to see if the task has completed
once complete the request needs to be retrieved from the service.
Could someone give me some suggestions or point me in the right direction?
The way I have typically handled asynchronous server-side processing is by:
Have the webpage initiate a request against a webservice and have the service return an ID to the long-running transaction. In my case, I have used Ajax with jQuery on the client webpage and a webservice that returns data in JSON format. ASP.NET MVC is particularly well suited for this, but you can use ASP.NET to return JSON string in response to a GET, or not use JSON at all.
Have the server create a record in a database that also stores the associated data to be processed. The ID of this transaction is returned to the client webpage. The service then sends a message to a third service via a message queue. In my case, the service was a WCF service hosted in a Windows Service with MSMQ as the intermediary. It should be noted that it is better not to do the actual task processing in ASP.NET, as it is not meant for requests that are long-running. In a high demand system you could exhaust available threads.
A third service receives and responds to the queued message by reading and processing necessary data from the database. It eventually marks the database record "complete".
The client webpage polls the webservice passing the transaction record ID. The webservice queries the database based on this ID to determine if the record is marked complete or not. If it is complete, it queries for the result dataset and returns it. Otherwise it returns an empty set.
The client webpage processes the webservice response, which will either contain the resulting data or an empty set, in which it should continue polling.
This just serves as an example, you may find that you can take shortcuts and avoid doing processing in a third service and just use ASP.NET threads. But that presents it's own problems, namely how you would have another request (the polling request) know if the original request is complete. The hackish-solution to that is to use a thread-safe collection in a static variable which would hold a transaction ID/result pair. But for that effort, it really is better to use a database.
EDIT: I see now that it appears to be a demonstration rather than a production system. I still stand by my above outline for "real-world" situations, but for a demo the "hackish" solution would suffice.
Which part are going to need to do async ? As far as I can tell your actions are synchronous:
1) -> 2) -> 3)
A simple web service would do, IIS (as any web server) supports multiple request to be handled async so you have no problem.
Something which you may need to be aware of. And also the javascript engine executes code in a single thread.
Step 0: Create the web service.
Step 1: Create the web app project (assuming it's ASP.NET).
Step 2: Add a web reference to the webs service to your web app project.
Step 3: The reference would create a proxy for you, using which you can invoke both synchronous and asynchronous calls.