I'm trying to figure out exactly how to set up my channelFactory and channels - to reuse the same instance vs creating new for each call. I've done a lot of research and I see many conflicting opinions. I'm coming to the following conclusion, but I'm not sure, so I'd like to hear some expert advice.
Using .NET 4, I'm creating a channel factory, adding an endpoint behavior, and then making calls.
Seems like I should reuse the same instance of channel factory but probably safest to make sure it's open first incase it faulted for any reason
If the factory faulted, try factory.close() and in a catch factory.abort()
Seems like there will not be a lot of overhead by doing factory.CreateChannel() for each call and that this is probably safer than sharing channels.
For each call, I should try ((IChannel)_client).Close() and in a catch((IChannel)_client).Abort();
One more thing that I'd like to confirm but I don't know how to test - is let's say I reuse channels and then the channel gets into faulted state - if I didn't code to check the state of the channel first, what would happen there?
Or should I share my channels - auto open with the first call and not close until I close my form?
Related
I don't know too much about services so if I am trying to do something they are not intended for please forgive me.
I am trying to wright dispatching software for a family member. They plan on starting with 3 or 4 dispatchers but it may scale in the future. I need the software to constantly (every 5 or 10 seconds at the very least) check and see if a new unhandled call has been placed when not in a call or if they are in a call see if another dispatcher updated the call (due to a call in with additional information).
Which option would be better for the above scenario
A) Have a table in a database that tracks updates to calls/ new calls and poll it every 5 - 10 seconds from every instance of the software.
B) Have a service running on the machine that has the database and have that service take care of all SQL. Create an instance of each call in the service and then just ask the service if there are any changes or unhandled call.
If B, is it possible to create a delegate in the service that the software on another (networked) machine can subscribe to? If so where might I find information on doing that, I could not find anything on google.
This is kind to broad.
However, you can use the following
DB Trigger to watch for inserts ect, then do and fabulous db stuff when triggered.
Create a Windows Service that polls, thats not a problem at all.
You could even self host a WCF server with a Duplex Contract that other software subscribes to, you could then send notifications ect via that channel.
or use SignalR for notification which would work just fine in this situation as well, and is a 5 minute job to get working.
Though, there is lots of approaches here, You really need to do some research to find what suits you most
Solution B is better.
If B, is it possible to create a delegate in the service that the
software on another (networked) machine can subscribe to? If so where
might I find information on doing that, I could not find anything on
google.
It depends on your need and project type.
You can use SignalR in ASP.Net
If you work with sockets you can keep connection alive and store client context in a list and notify theme
We are currently developing a software solution which has a client and a number of WCF services that it consumes. The issues we are having is WCF services timing out after a period of inactivity. As far as I understand, there are 2 ways to resolve this:
Increase timeouts (as far as I understood, this is generally not recommended. Eg. setting timeout to infinite/weeks is considered bad practice)
Periodically ping the WCF services from the Client (I'm not sure that I'm a huge fan of his as it will add redundant, periodic calls)
Handle timeout issues and attempt to reconnect (this is slow and requires a lot of manual code)
Reliable Sessions - some sources mention that this is the in-built WCF pinging and message reliability mechanism, but other sources mention that this will still time out.
What is the recommended/best way of resolving this issue? Is there any official reading material on this? I could not find all that much info myself
Thanks!
As i can see, you have to use a combination of your stated points.
You are right, increasing the timeouts is bad practice and can give you a lot of problems.
If you don't want to use Reliable Sessions, then Ping is the only applicable way to hold the connection.
You need to handle this things, no matter if a timeout occurs, the connection is lost or a exception is thrown. There are a plenty of possibilities that your connection can fault.
Reliable Sessions are a good way not to implement a ping, but technically, it does nearly the same. WCF automatically sends an "I am still here" Request.
The conclusion of this is, that you need point 3 and point 2 or 4. To reduce the manually code for point 3, you can use Proxies or a wrapper around your ServiceClient, that establishes a new connection if the old one is faulted during a request. Point 4 is easy to implement, because you only need some small additions to your binding in your config. And the traffic overhead is not that big. Point 2 is the most expensive way, you need to handle a Thread/Task that only pings the server and the service needs to be extended. But as you stated before, Reliable Sessions can fail, and Pings should bring you on the safe side.
You should ask yourself what is your WCF endpoint is doing? Is the way you have your command setup the most optimal?
Perhaps it'd be better to have your endpoint that takes a long time be based on a polling system that allows there to be a quick query instead of waiting on the results of the endpoints actions.
You should also consider data transfer as a possible issue. Is the amount of data you're transferring back a lot?
To get a more pointed answer, we'd need to know more about the specific endpoint as well as any other responsibilities there are for the service.
First of all, I am creating a something like a client/server solution using a standard ASP.NET website - I do know this method is not adviced, and most people would love to scream "COMET!" or "HTML5 Sockets!" - but please don't ;-) !
What I am doing...
I am creating an MMORPG on a website.
I have several clients whom need to be in contact at the same time. This is done by a global object in the Application scope.
My problem
I need to invoke an event to several clients. For instance, when an attack has been performed, I need to update some graphics. The attack logic is resolved in the global object, but each of the clients has to respond to this.
Right now I do the following:
fightTrace.Reciever.InvokeMoveEnded(this);
fightTrace.FiredBy.InvokeMoveEnded(this);
(This is a kind of observer pattern)
What now happends is a race condition. The one who loads the page_load event will get both of these events, and the one who is not running them, will experience no changes in the UI.
So what is it I really want?
What I really need is some genuine and nice way to create an observer pattern through the application state. I need to send an event out to every "listener" which is in this case is a client, and then do some update.
One way to do this is some session-thing, with true/false.. But I would really like some better way!
Thanks!
If I understood your context correctly then whenever the state of your application state object is changed you want to synchronize all the clients of your applications. What you are forgetting here is the stateless behavior of HTTP protocol. Once a response is sent the connection is lost you need to send an HTTP request again to be served again. However you can emulate some thing using State Management and Ajax based short and timely updates to simulate a connected environment. However I've to utter the words which you don't want to hear. Not recommended.
Instead what you can do is to save the state of application object and whenever a request comes serve the response based on updated state of your object. Any how a client has to initiate a request.
I have created a simple WCF (.NET 3.5) service which defines 10 contracts which are basically calculations on the supplied data. At the moment I expect quite few clients to make a call to some of these contracts. How do I make the service more responsive ? I have a feeling that the service will wait until it process one request to go to the next one.
How can I use multithreading in WCF to speed things up ?
While I agree with Justin's answer, I believe some more light can be shed here on how WCF works.
You make the specific statement:
I have a feeling that the service will
wait until it process one request to
go to the next one. How can I use
multithreading in WCF to speed things
up ?
The concurrency of a service (how many calls it can take simultaneously) depends on the ConcurrencyMode value for the ServiceBehavior attached to the service. By default, this value is ConcurrencyMode.Single, meaning, it will serialize calls one after another.
However, this might not be as much of an issue as you think. If your service's InstanceContextMode is equal to InstanceContextMode.PerCall then this is a non-issue; a new instance of your service will be created per call and not used for any other calls.
If you have a singleton or a session-based service object, however, then the calls to that instance of the service implementation will be serialized.
You can always change the ConcurrencyMode, but be aware that if you do, you will have to handle concurrency issues and access to your resources manually, as you have explicitly told WCF that you will do so.
It's important not to change these just because you think that it will lead to increased performance. While not so much for concurrency, the instancing aspect of your service is very much a part of the identity of the service (if it is session or not session-based) and changing them impacts the clients consuming the service, so don't do it lightly.
Of course, this speaks nothing to whether or not the code that is actually implementing the service is efficient. That is definitely something that needs looking into, when you indicate that is the case.
This is definitely pre-mature optimization. Implement your services first and see if there's an issue or not.
I think you'll find that you are worrying about nothing. The server won't block on a single request as that request processes. IIS/WCF should handle things for you nicely as-is.
I'm not familiar with WCF, but can the process be async?
If you are expecting a huge amount of data and intensive calculations, one option could be to send an id, calculate the values in a separate thread and then provide a method to return the result using the initial id.
Something like:
int id = Service.CalculateX(...);
...
var y = Service.GetResultX(id);
By default the Instancing is PerSession.
See WCF Service defaults
However if you use a session binding that doesn't support sessions (like BasicHttpBinding) or the the channel/client does not create a session then this behaves like PerCall
See [Binding type session support] (https://learn.microsoft.com/en-us/dotnet/framework/wcf/system-provided-bindings).
Each WCF client object will create a Session and for each session there will be a server instance with a single thread that services all calls from that particular WCF client object synchronously.
Multiple clients therefore would each have their own session and therefore server instance and thread by default and would not block each other.
They will only affect each other on shared resources like DB, CPU etc.
See Using sessions
Like others suggested you should make sure the implementation is efficient BEFORE you start playing with the Instancing and Concurrency modes.
You could also consider client side calculations if there is no real reason to make a call to the server.
Since this question tells me that SoapHttpClientProtocol is not thread safe. And, my real life testing tells me this is true, as my SoapHeader properties keep getting mixed up between calls. Is there a way to make sure that I can use this across threads and keep my properties correct? And make sure I don't run into the example given in that question of one thread thinking the connection is open, when another thread has closed it? Do I need to worry about the soap header values after my request has been made? How can I verify the properties are as I set them until the request has been issued?
The first thing I would ask is does your service work correctly if you do not make it multi-threaded. If you make subsequent calls do they all work correctly and give you the desired results? If not then there is a problem on the server side more than likely.
To see what you are sending you could serialize down the soap message before it goes. Make sure it's getting generated correctly.
My job blocks access to a lot of websites but CodeProject has some examples if I remember correctly.
If the single thread works have the serialization layer in place and have it write the files to disk in your multi-threaded scenario. Then you can see what is working and what is not by what your code thinks it's sending.
More than likely your calls are getting mixed by the server since you are trying to establish multiple connections while it may be seeing your endpoint as one value, kind of like being behind a NAT firewall. Which means you may be getting a connection but one of your other threads gets its message through first. If that is the case you could try spinning each thread up in it's own app domain and see if it does anything for you. Not saying that it will work, but not sure off the top of my head what else may be available for you to try.