I have a Web service create by WCF, and it could response for the client's request, such as adding or updating data.
Let's call the main part of service Context, because some method(supposed method A) would spend a long time to handle, but I don't want the method hold the server, I set the InstanceContextMode enum to PerCall, and I expect that each time I call A, it will create a new instance to serve the request, then my server could continue to server other one's as usual.
But my problem is, it still use Main thread(UI thread) to serve each time, so when I call A, the server will stop response for a long time, till A done.
Did I miss anything? I'm a novice of WCF, so please let me know if I had any mistake.
Related
I have a system, that request data from a WCF webservice
it is like so:
WCF1 calls WCF2, WCF2 calls WCF3 and WCF3 do its job and returns response
My problem here is some of the operations takes a long time "about 2 min" to process
So if WCF1 send a request that takes long of time, and then another request from WCF1 that should take a second, it will wait until the first request finishes
i read about the problem, some of users said to use
<ServiceBehavior(ConcurrencyMode:=ConcurrencyMode.Multiple, InstanceContextMode:=InstanceContextMode.PerCall)> _
this doesn't solve the problem 100%
Can u please advice
I do not think those settings will solve your problem.
From the source:
In PerCall instancing, concurrency is not relevant, because each
message is processed by a new InstanceContext and, therefore, never
more than one thread is active in the InstanceContext.
Bottom line, because you are using PerCall activation, there is no point in adding the ConcurrencyMode.Multiple as each incoming request will get its own instance of the service class to handle its request.
You should try to narrow down what is really causing the performance problem. Look at the underlying code that your WCF services are calling.
EDIT
From another SO post.
In terms of behavior: ConcurrencyMode does not matter for a PerCall
service instance.
In terms of performance: A PerCall service that is
ConcurrencyMode.Multiple should be slightly faster because its not
creating and acquiring the (unneeded) thread lock that
ConcurrencyMode.Single is using.
In a client server WCF duplex scenario, what is the recommended way to let the server know that an error occurred on the client side? Let's say that the server notifies one of the clients that it needs to perform a certain operation and an exception is being thrown on the client side.
On the callback interface, I have something like this
[OperationContract(IsOneWay = true)]
void Work(...);
What's the best approach:
Implement a NotifyServer(int clientId, string message) message that the client can call to let the user know that the requested operation failed,
If I set IsOneWay = false on the operation contract, would I have to call every client on a BackgroundWorker thread in order to keep the UI responsive?
Implementing async operations on the server? How will this work? I can generate async operation on the client, will I have to use the same pattern (BeginWork, EndWork) for the client callback method?
Can't think of anything else, because throwing a FaultException on the client side when IsOneWay = true will not work.
Any advice?
Thank you in advance!
Ad 1. That is one way of doing it... recommended if the Work() may take unpredictable amount of time and you do not want your server thread hanging on that call.
Ad 2. You should always perform WCF operations in the background worker and never inside the UI thread.. If you set IsOneWay=False then obviously Work() method will block on the server until it has finished executing on the remote client and returns results. However even if you set isOneWay=true the method will still block on the low-level WCF communication. If WCF connection is dropped, this can be a long time, before you get notified.
Ad 3.
The pattern is up to you.
Example: MSDN: OperationContractAttribute.AsyncPattern Property
No best solution exists. It all depends on your setup (classes, threads, etc). The WCF layer you code should be easy and convenient to use - that is the main guide line.
i am building a WCF Service and i need clients to be able to acquire multiple results in the same time.
For example 5 callings of void UploadPhoto(byte[] photo);
and 1 string GetInfo()
If I understand it correctly, than whenever I do a request for a service, I need to get a response for the first one before the second gets proceeded. Is that correct?
Thanks
You can make multiple calls if you increase the System.Net.ServicePointManager.DefaultConnectionLimit the default is 2.
You need to set the WCF Service as Per-Call Service to process concurrent requests.
That is not quite correct.
If you call a WCF (or other web service) syncronosly then you have to wait for the response before doing anything else.
However, you can call a wcf service asyncronosly, in which case you do not have to wait for the result. You create a handler that handles the result when it comes back, but the main program continues.
Have a look at Ladislav's answer to this question: Difference between WCF sync and async call?
I am trying to create a XAMLX service that I can fire and forget.
But how can I do something like that with a XAMLX? I have no access to the Contract Interface to add the [OneWay] attribute.
I thought that if I did something like
and put the response before the rest of the activities, the service would return at that point but it didn't. It returns only after the whole workflow is completed.
IS it possible to make the service return at that point and than continue with the processing. the other activities would not affect the returned value of the service.
Is it possible to create a fire and forget XAMLX service
Can I somehow make the client fire a normal service as oneWay, if the previous 2 points are not possible?
If you want one-way processing your Receive activity should not have any corresponding SendReply activity.
The reason the response isn't send immediately is the way the workflow scheduler works internally where it waits for the workflow to go idle. Nothing much you can do about the scheduler but if you add a Delay below the SendResponse with a duration of 1 millisecond.
As Ladislav said, remove the SendResponse and you get a one way message.
Not quite sure what you want with fire and forget. If you start a workflow service it will keep on running even if you don't send any more WCF requests to it. Even if it is long running or does other async work. No problems there.
Just trying to get my head around what can happen when things go wrong with WCF. I have an implementation of my service contract declared with an InstanceContextMode of PerSession...
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
The calls happen as follows:
My client calls the server and calls GetServerUTC() to return the current UTC time of the server. This is a one way call and the server will call the client back when its ready (trivial in this instance to simply return the current time!)
The server calls back to the client and for test purposes in the callback implementation on the client I throw an exception.
This goes unhandled in the client (for test purposes) and the client crashes and closes down.
On the server I handle the faulted event handler on the ICommunicationObject...
obj.Faulted += new EventHandler(EventService_Faulted);
Questions...
Will this kill off the session for the current connection on the server.
I presume I am free to do what I want in this method e.g. logging or something, but should I do anything specific here to terminate the session or will WCF handle this?
From a best practise view point what should I do when the callback is faulted? Does it mean "something has happened in your client" and thats the end of that or is there something I a missing here?
Additionally, are there any other faulted handlers I should be handling.
Ive done a lot of reading on WCF and it seems sort of vague on what to do when something goes wrong. At present I am implementing a State Machine on my client which will manage the connection and determine if a user action can happen dependant on if a connection exists to the server - or is this overkill.
Any tips would be really appreciated ;)
I found out that the session will time out as per the settings for your sessions. Strangely I noticed that once faulted the client is still able to call other methods on the same session.