NetworkStream Pooling - c#

I have a multi-threaded application which communicates with a server over a TCP connection. The application would be deployed as a windows service.
The way it has been implemeted is, there is Controller which creates Communicator objects, assigns the port number, message count etc. properties to the Communicator and invokes its StartClient method to commence the dialog with the server.
Within the StartClient method, each Communicator object creates a connection to the server, using the port number and url specified by the Controller. After establishing the connection, it internally creates a thread and calls the ReadMessages method which keeps reading from the server till the message count is met and then gets closed down.
Based on the runtime conditions, there might be a need to reuse the Communicator object to talk with the server again and hence, the ReadMessages method woudl be called again.
Initially, we had been calling Dispose() method for the NetworkStream, StreamReader and StreamWriter objects when the ReadMessages method completed, but with the reconnecting scenario, it used to throw "Cannot access a disposed object" error. So, we commented out the Dispose method call for testing.
As of now, it works fine, but I am concerned that, this isnt the best way to achieve this functionlity as I am not disposing the objects ever.
I was thinking in terms of object pooling, If it is possible to have a pool of Stream objects which could be reused by different threads?
One way to tackle this can be to create a new instance of Stream objects each time the Communicator connects with the server, but I think that would be an expensive operation.
Can you please help me identify a better approach to handle the situation here so that I can reuse the Communicator object without a performance hit?

The approach will be based on how frequently you need to read messages - if its occasional the n, I would recommend that you re-factor your communicator object to make "ReadMessages" operation atomic - i.e. it would connect to the server, create network stream, read messages and then dispose every thing.

Related

WCF - Is GetCallbackChannel reliable?

In the part "Figure 5 Storing the Callback References for Later Use" of this tutorial, it's clear that the service would need to keep the manual cache list synchronized reflecting the connected clients only to prevent exceptions caused by the reference to old clients that got disconnected. But, if I don't plan to use such a cache mechanism (for which I don't see any need at all) and I directly access GetCallbackChannel<T> instead to perform event calls to the client, is it guaranteed that the internal list will only contain all connected clients and would never throw a corresponding CommunicationException when calling a contained event?
Sorry, I hadn't read here where it says:
Gets a channel to the client instance that called the current
operation.
This immediately causes the "Figure 5 Storing the Callback References for Later Use" part of the first tutorial to make sense now, as we'll call the clients (supporting multiple in fact) in another thread (so deferred to their requests). I thought GetCallbackChannel simply represented the whole acknowledged callbacks (one per client) at any point of the service execution.
I understand then I'll naturally have to catch exceptions such as CommunicationException once I mimic that caching list approach (or simply Exception only).

Right way of using WCF service client [duplicate]

This question already has answers here:
Best Practice for WCF Service Proxy lifetime?
(4 answers)
Reuse of WCF service clients
(2 answers)
Closed 9 years ago.
I have a UI application in which I consume a WCF service like this
public MainWindow()
{
....
mServiceClient = new ServiceClient("EndPointTCP");
}
Should I create the client as a member of class and close the client along with exit of my application or Should I create a new client whenever its required in a method and close there itself.
It depends solely onwhat you want to achieve. There is no "best way to do it" since both ways are possible, good, and have different tradeoffs.
Holding the clientobject simply wastes resources. It also may leak context data between calls. You might have a bug that will cause mClient.Buy(100) and mClient.Sell(100) to work properly when used alone, but fail when used together mClient.Buy(100); mClient.Sell(100). Dropping and re-creating fresh instance each time could save you from that one bug, but obviously that's not a good argument for it.
Recreating the client each time a call is to be made has however the vague benefit of .. having a fresh client every time. If your app has a possibility to dynamically change the endpoint during the app's runtime, then automatically your client will be always using the newest addresses/logins/passwords/etc.
However, not recreating the client object at every time is simply faster. Mind that it's WCF layer, so the actual underlying connection can be any. Were it some protocol with heavy setup with some keyexchange, encryption, etc, you may find that creating a new client every time might create a new connection at every time and it will slow down eveyrthing, while keeping the instance will work blazingly fast, since connection might be kept open and reused. Often you try to keep the connection when you have to perform many and often calls to the service, like 24h/day twice/sec monitoring some remote value for breaching safe limits.
On yet the other hand, you might not want the connection to linger. Your remote service may have thousands of clients and limited resources, so you might want to close the connection ASAP so others may connect. Often you'd do it like that when the calls to the service are really rarely done, only once in a time, ie. when user clicks after returning from coffe break.
Please don't get me wrong: all above is just conjuring some vague "facts" from a void. I do not know your app, nor your service, nor your bindings (sans "endpoint TCP"). The most important factors are all on your side and they sit in the actual way how your app and that remote service work and interoperate. If you care about what you ask, you must first simply research the topic on your side. Best - simply try both ways and check if it works and how does it perform. The difference would be something like 2..6 lines of code, so that's, well, rather quick.
There are already some similar questions:
Reuse of WCF service clients
Reusing a WCF service client or creating one each time?
In my opinion it depends on your application type (scalability, performance requirements, ...) but usually I think that it's more safe to recreate the ServiceClient each time. In this way you don't need special code if there are connections problems between requests and with the latest version of WCF seems that there isn't a big performance impact.
See http://msdn.microsoft.com/en-us/library/aa738757.aspx.
Consider also that ServiceClient is not thread safe (at least reading MSDN).

web methods and DB connections

If I open some DB connection in some global viable in one call of the web service's method and if concurrently at second call of this method will it see this instance in this global viable ? Are this resources shared or each call has it's own resources ?
Thanks
Global variables tend to be just that, global. If your global variable is a C# static, it will be shared by webservice methods in the AppDomain. This is obviously error-prone - It is better, if each webservice method obtains a new connection when needed, and close it before the method finishes.
Usually Web service use Http request.
In this case it's possible that each call you have to define the object, because the service are stateless...
For services it is better to use some kind of database connection management. Usually you can adapt Open/Close new connection on per-request basis. Note, most likely you will be working with logical connections and connection pool. Those are helpful to significantly reduce load to open physical connection. Physical connection is created without your direct control and is really heavy weight operation.
Do not put connection in a shared static variable, because connection is typically a disposable resource, which means you must dispose it. If something goes wrong and your connection to the database is corrupted then all your subsequent calls are deemed in doom.

Tibco EMS Session sharing Connection object

Our connectivity to EMS code was initially ill-designed and created one TopicConnection object per topic that we listened to. So, in effect, whenever we subscribed to a topic, we create a new connection, a new session and, lastly, a new listener.
We would like to switch to a single connection model. Although I am able to do this easily in our code by sharing one connection object and creating a new session object per topic, we are unsure whether this is going to cause any issues without code.
My understanding is that the Tibco EMS client library is thread safe with regards to sharing a connection. In effect, a connection is just a pipe and the sessions can resuse the this pipe in a thread safe manner.
Is this assumption correct or is there more to this?
The .NET EMS API is based on JMS. In JMS, the Connection and Session objects are specified to be thread-safe and can be reused within the program. You are quite correct in that the Connection object simply represent a network pipe to the EMS server. The EMS User's Guide states:
A connection is a fairly heavyweight object, so most clients will create a connection once and keep it open until the client exits. Your application can create multiple connections, if necessary.
And regarding sessions:
A Session is a single-threaded context for producing or consuming messages. You create Message Producers or Message Consumers using Session objects.
Essentially, unless you need very large volumes and are bumping into performance limitations, it's perfectly safe to use just one connection in your application. The session controls the transaction/acknowledgement semantics of any producers or consumers created within, but is again safe to reuse. I would probably use separate sessions for modules exist within the application with distinct life cycles (think separate deployment units within an application server).
Your EMS server installation will contain a samples directory with various code (something like C:\tibco\ems\5.0\samples\cs). The code in csTopicSubscriber.cs shows how to write a single-threaded topic consumer. There is no multi-threaded topic consumer example but csMsgConsumerPerf.cs demonstrates how to do it with queues.
Be sure to clean up any objects you create after you're done with them - e.g. close the topic consumer object, the session, and the connection when you're finished. Leaking handles without closing them can result in unpredictable behaviour when combined with prefetch and fault-tolerant reconnect settings.
I think yes as long as sharing is within the same application (exe, binary).
We have shared same connection object, and used it as a singleton in our code.
Agree with an earlier answer: the JMS Session must not be shared between threads, but the Connection can/should be. So one connection per application is ok (make sure you start/close it only once - best before/after the individual threads creation).
And then create and use one Session per thread. Remember that when you close() a Session, it will block until all receive callbacks have really returned. So do NOT call close() from within a callback's onMessage().

static WCF proxy class object

I have a WCF app on NetTCP Binding based. In client app i have created its proxy class object as static. This client app may run for 4-8 hrs after deployment. Basically at login window I am creating and initializing DataServiceClient proxy class (mainly database insert & updates) and using same object throughout my application until user closes Main Window.
Is there any adverse effect (performance wise) of creating static object of proxy class? If yes then how I can avoid this. Before using static object I was creating individual object at every window (wherever required) but this had increased window loading time.
How I can improve WCF performance. I am satisfied with its performance but it could be my illusion.
Nothing wrong with using the same instance, but make sure your error handling is good. Otherwise the proxy object will go into a faulted state when an error happens and you have to restart the whole application. There are some events you can attach to when the state changes.
After the proxy object goes into the faulted state you have to create a new one, there is no way to recover a faulted proxy object.
I have found that using message headers reduces the amount of methods I actually need to expose, but that really depends on what your service does.
Otherwise I would recommend to use streaming when possible. Keep your data as small as possible. Use the binary formatter.
Looks like you client is a Windows Forms application - a static service proxy should be ok for you as long as you don't do any multi-threading or callbacks on your proxy etc. Essentially, in such case, you need to synchronize the access to static variables.
Talking in general terms, WCF performance can be improved
Designing the service contract carefully - its should be chunky interface and not chatty so that number of service calls gets reduced
Choosing appropriate binding - TCP Binding would be faster than HTTP Binding but it would be .NET propriety and may not work over internet as other ports would be blocked. If your communicating on same machine then named piped binding would be the fastest mode

Categories