RAPI Approach: 1 static instance for the entire winforms app vs create,connect,dispose - compact-framework

In many places in our application we have code like this:
using(RAPI rapi = new RAPI())
{
bool connected = TryToConnectWithTimeout(rapi);
if(connected)
DoSomethingWithRapi(rapi);
}
This has worked well so far.
We never have more than 1 rapi instance at a time. Until now:
But now we want to listen for the connect event on rapi.
We are doing it like this:
void StartMonitoringRapiConnection()
{
_rapi = new RAPI();
_rapi.RAPIConnected += new RAPIConnectedHandler(_rapi_RAPIConnected);
_rapi.RAPIDisconnected += new RAPIConnectedHandler(_rapi_RAPIDisconnected);
_rapi.Connect(false,-1);
}
private void _rapi_RAPIConnected()
{
DoWorkWhenRapiConnects();
}
private void _rapi_RAPIDisconnected()
{
//Listen for the next time that rapi connects
_rapi.Connect(false,-1);
DoWorkWhenRapiDisconnects();
}
"StartMonitoringRapiConnection" works pretty well as long as I do not start to new up and connect other RAPI objects. But once I start newing up other RAPI objects, the connect/disconnect events seem to fire out of order.
Would it work better to have just 1 static instance of RAPI for the entire app? Do you have any other advice? Thanks.

Logically, RAPI is a single connection between the PC and the device. It doesn't make sense for your app to even support multiple connections. I'd make a Singleton class that wraps up the RAPI calls and makes all of your calls for you so that everyone that needs to talk to the device goes through that one class.

Related

Single Responsibility Principle the correct approach

SRP really bug me. I know how to find responsibility what I dont know is how to assemble them correctly
e.g
class Modem{
public void dial(){//code here}
public void hangup(){//code here}
public void send(){//code here}
public void recive(){//code here}
}
In this common example we have connection and communication responsibility. So we divide that into 2 new interfaces
interface Connection{
public void dial();
public void hangup();
}
interface Communication{
public void send();
public void recive();
}
implement them:
class SimpleModemConnection implements Connection{
public void dial(){//code here}
public void hangup(){//code here}
}
class SimpleModemCommunication implements Communication{
public void send(){//code here}
public void recive(){//code here}
}
and at this point I dont really know how client code should look like
Do I aggregate those intefaces into Modem class ?
class Modem {
Connection connection = new SimpleModemConnection();
Communication communication = new SimpleModemCommunication();
}
main(){
Modem modem = new Modem();
modem.connection.dial();
modem.communication.send();
modem.communication.recive();
modem.connection.hangup();
}
Do I use them directly
main(){
Connection connection = new SimpleModemConnection();
Communication communication = new SimpleModemCommunication();
connection.dial();
communication.send();
communication.recive();
connection.hangup();
}
Or is there some other way?
I am afraid you may be overthinking this. A Modem needs to both connect and communicate. Unless you know of and expect a situation where these two can be separated out, there is simply no point in splitting this up. At the end, these principles should not be the primary driving force of your design. That should be your knowledge of the domain and the kind of changes you expect in the system.
So what you need to answer is if your Modem class would ever need to swap out its connection/communication subsystems?
This can be very confusing some times. I struggle with the same questions daily, but it's good that you think about it. I have been actively pursuing the use of the SOLID principles along with my TDD practices. One thing that it seems like you are not thinking of here is who will be using your modem, unit tests and actual object users in code.
In my mind it works like this. Modem has the responsibility of Dialling, hanging up, sending and receiving data, so those are the functions exposed to the user of you API (with the exception of Receive), whether it be your unit tests or your in code user. Therefore the following would exist.
IModem.cs
interface IModem
{
public bool Connect(); // Seen in your code as dial
public void Disconnect(); // Seen in your code as hangup
public void SendData(); // Take data as parameter
// Receive will not be public, instead I would make it call out to the user saying "I have received data for you"
}
This clearly states that the responsibility of your Modem Object is to Connect, Disconnect and Send data to where it needs to go. Now whether the modem does the connection and communication is the other question. I would say that what you have with your SimpleConnection and SimpleCommunication modules are perfect (I would change the naming a little ;) ). Connection becomes IConnectionModule and Communication becomes ICommunicationModule, as well as some function name changes. dial to Connect, hangup to Disconnect and send to SendData. Having that in mind I take the following approach.
Responsibility of my Modem: My modem will use the modules it has to connect the user to a remote host, as well as disconnect from the host or send any data necessary.
The definition above then results in the following code.
Modem.cs
class Modem : IModem
{
private IConnectionModule _connectionModule;
private ICommunicationModule _communicationModule;
public Modem(IConnectionModule connectionModule, ICommunicationModule communicationModule)
{
_connectionModule = connectionModule;
_communicationModule = communicationModule;
}
public bool Connect()
{
bool connectionSuccess = _connectionModule.Connect()
return connectionSuccess;
}
public void Disconnect()
{
_connectionModule.Disconnect();
}
public void SendData()
{
_communicationModule.SendData();
}
}
Looking at the above you can lay out the responsibilities as follows:
Modem: Serves as a bridge between the user of the API, allowing the user to send and receive information.
Connection Module: Connects the modem to a host (The user will never use this, the only user to use this will be it's unit test suite and the modem)
Communication Module: Sends information to an already connected host (The user will never use this, the only user to use this will be it's unit test suite and the modem)
The reason for "hiding" the modules from the user is because no user of a modem has to know about which connection module is being used. All you should have to do is call Connect/Disconnect and the functionality should be supplied. The rest should all be "invisible". Again, this depends solely on your development style but I always try to keep things nicely separated and make sure I always have one action per call. Whether it's farmed out to a different object or done within the class itself.
I hope this helps, let me know what you think, I am always up for discussions on designs and SOLID principles.

Is it better to use the Bus Start method or a class constructor to instantiate objects used by a service

I'm using nServiceBus 5 and have created a number of host endpoints, two of which listen for database changes. (The specifics of how to do this can be found here). The intention is to have a service running in the background which publishes an event message using the Bus when notified to do so by the database listener.
The code which creates the database listener object and handles events is in the Start method, implemented as part of IWantToRunWhenBusStartsAndStops.
So - Is putting the code here likely to cause problems later on, for example if an exception is thrown (yes, I do have try/catch blocks, but I removed them from the sample code for clarity)? What happens when the Start method finishes executing?
Would I be better off with a constructor on my RequestNewQuoteSender class to instantiate the database listener as a class property and not use the Start method at all?
namespace MySample.QuoteRequest
{
public partial class RequestNewQuoteSender : IWantToRunWhenBusStartsAndStops
{
public void Start()
{
var changeListener = new DatabaseChangeListener(_ConnectionString);
// Assign the code within the braces to the DBListener's onChange event
changeListener.OnChange += () =>
{
// code to handle database change event
changeListener.Start(_SQLStatement);
};
// Now everything has been set up.... start it running.
changeListener.Start(_SQLStatement);
}
public void Stop() { LogInfo("Service Bus has stopped"); }
}
}
Your code seems fine to me.
Just a few small things:
Make changeListener a class field, so that it won't be GC (not 100% sure if it would be but just to make sure);
Unsubscribe from OnChange on the Stop() method;
You may also want to have a "lock" around changeListener.Start(_SQLStatement); and the Stop so that there are no racing conditions (I leave that one up to you to figure out if you need it or not);
Does this make sense ?

Memory leak using WCF GetCallbackChannel over named pipe

We have a simple wpf application that connects to a service running on the local machine. We use a named pipe for the connection and then register a callback so that later the service can send updates to the client.
The problem is that with each call of the callback we get a build up of memory in the client application.
This is how the client connects to the service.
const string url = "net.pipe://localhost/radal";
_channelFactory = new DuplexChannelFactory<IRadalService>(this, new NetNamedPipeBinding(),url);
and then in a threadpool thread we loop doing the following until we are connected
var service = _channelFactory.CreateChannel();
service.Register();
service.Register looks like this on the server side
public void Register()
{
_callback = OperationContext.Current.GetCallbackChannel<IRadalCallback>();
OperationContext.Current.Channel.Faulted += (sender, args) => Dispose();
OperationContext.Current.Channel.Closed += (sender, args) => Dispose();
}
This callback is stored and when new data arrives we invoke the following on the server side.
void Sensors_OnSensorReading(object sender, SensorReadingEventArgs e)
{
_callback.OnReadingReceived(e.SensorId, e.Count);
}
Where the parameters are an int and a double. On the client this is handled as follows.
public void OnReadingReceived(int sensorId, double count)
{
_events.Publish(new SensorReadingEvent(sensorId, count));
}
But we have found that commenting out _event.Publish... makes no difference to the memory usage. Does anyone see any logical reason why this might be leaking memory. We have used a profiler to track the problem to this point but cannot find what type of object is building up.
Well I can partially answer this now. The problem is partially caused by us trying to be clever and getting the connection to be opened on another thread and then passing it back to the main gui thread. The solution was to not use a thread but instead use a dispatch timer. It does have the downside that the initial data load is now on the GUI thread but we are not loading all that much anyway.
However this was not the entire solution (actually we don't have an entire solution). Once we moved over to a better profiler we found out that the objects building up were timeout handlers so we disabled that feature. That's OK for us as we are running against the localhost always but I can imagine for people working with remote services it would be an issue.

WCF events in server-side

I'm working on an application in WCF and want to receive events in the server side.
I have a web that upon request needs to register a fingerprint.
The web page request the connection of the device and then every second for 15 seconds requests the answer.
The server-side code is apparently "simple" but doesn't work.
Here is it:
[ServiceContract]
interface IEEtest
{
[OperationContract]
void EEDirectConnect();
}
class EETest : IEEtest
{
public void EEDirectConnect()
{
CZ ee = new CZ(); // initiates the device dll
ee.Connect_Net("192.168.1.200", 4011);
ee.OnFinger += new _IEEEvents_OnFingerEventHandler(ee_OnFinger);
}
public void ee_OnFinger()
{
//here i have a breakpoint;
}
}
every time I put my finger, it should fire the event. in fact if I
static void Main()
{
EETest pp = new EETest();
pp.EEDirectConnect();
}
It works fine. but from my proxy it doesn't fire the event.
do you have any tips, recommendations, or can you see the error?
Thanks everyone.
I can see two issues with your code, which may or may not be the problem.
A) Event Registration Race Condition
You call CZ.Connect_Net() and THEN you register with the event handler. So if your event fires between calling Connect_Net() and you registering a method to handle the event then you'll not see it. Register the event handler first and then call Connect_Net().
B) EEtest lifetime.
The life time of your EEtest class depends on the Instancing Mode you use in WPF, see http://mkdot.net/blogs/dejan/archive/2008/04/29/wcf-service-behaviors-instance-and-concurrency-management.aspx. Generally the default is Per-Call which means a new instance of EEtest is created just to service the call to EEDirectConnect. So when you invoke the method EEDirectConnect you get this:
EEDirectConnect invocation started.
WCF makes a new EEtest class.
WCF invokes the method on EEtest.
The method news up a CZ and invokes the Connect-net method.
The event handler is attached.
The method EEDirectConnect completes.
EEtest is now "unrooted" by WCF - it's eligible for GC, and hence CZ is eligible for GC.
So perhaps it takes a very short time (or it's synchronous) and the problem is A, or it's asynchronous and it takes a little bit longer and it's B.
BTW: To fix B you could use some sort of synchronisation mechanism (eg an Event) to block until ee_Onfinger fires.

What is the proper life-cycle of a WCF service client proxy in Silverlight 3?

I'm finding mixed answers to my question out in the web. To elaborate on the question:
Should I instantiate a service client proxy once per asynchronous invocation, or once per Silverlight app?
Should I close the service client proxy explicitly (as I do in my ASP.NET MVC application calling WCF services synchronously)?
I've found plenty of bloggers and forum posters out contradicting each other. Can anyone point to any definitive sources or evidence to answer this once and for all?
I've been using Silverlight with WCF since V2 (working with V4 now), and here's what I've found. In general, it works very well to open one client and just use that one client for all communications. And if you're not using the DuplexHttBinding, it also works fine to do just the opposite, to open a new connection each time and then close it when you're done. And because of how Microsoft has architected the WCF client in Silverlight, you're not going to see much performance difference between keeping one client open all the time vs. creating a new client with each request. (But if you're creating a new client with each request, make darned sure you're closing it as well.)
Now, if you're using the DuplexHttBinding, i.e., if you want to call methods on the client from the server, it's of course important that you don't close the client with each request. That's just common sense. However, what none of the documentation tells you, but which I've found to be absolutely critical, is that if you're using the DuplexHttBinding, you should only ever have one instance of the client open at once. Otherwise, you're going to run into all sorts of nasty timeout problems that are going to be really, really hard to troubleshoot. Your life will be dramatically easier if you just have one connection.
The way that I've enforced this in my own code is to run all my connections through a single static DataConnectionManager class that throws an Assert if I try to open a second connection before closing the first. A few snippets from that class:
private static int clientsOpen;
public static int ClientsOpen
{
get
{
return clientsOpen;
}
set
{
clientsOpen = value;
Debug.Assert(clientsOpen <= 1, "Bad things seem to happen when there's more than one open client.");
}
}
public static RoomServiceClient GetRoomServiceClient()
{
ClientsCreated++;
ClientsOpen++;
Logger.LogDebugMessage("Clients created: {0}; Clients open: {1}", ClientsCreated, ClientsOpen);
return new RoomServiceClient(GetDuplexHttpBinding(), GetDuplexHttpEndpoint());
}
public static void TryClientClose(RoomServiceClient client, bool waitForPendingCalls, Action<Exception> callback)
{
if (client != null && client.State != CommunicationState.Closed)
{
client.CloseCompleted += (sender, e) =>
{
ClientsClosed++;
ClientsOpen--;
Logger.LogDebugMessage("Clients closed: {0}; Clients open: {1}", ClientsClosed, ClientsOpen);
if (e.Error != null)
{
Logger.LogDebugMessage(e.Error.Message);
client.Abort();
}
closingIntentionally = false;
if (callback != null)
{
callback(e.Error);
}
};
closingIntentionally = true;
if (waitForPendingCalls)
{
WaitForPendingCalls(() => client.CloseAsync());
}
else
{
client.CloseAsync();
}
}
else
{
if (callback != null)
{
callback(null);
}
}
}
The annoying part, of course, is if you only have one connection, you need to trap for when that connection closes unintentionally and try to reopen it. And then you need to reinitialize all the callbacks that your different classes were registered to handle. It's not really all that difficult, but it's annoying to make sure it's done right. And of course, automated testing of that part is difficult if not impossible . . .
You should open your client per call and close it immediately after. If you in doubt browse using IE to a SVC file and look at the example they have there.
WCF have configuration settings that tells it how long it should wait for a call to return, my thinking is that when it does not complete in the allowed time the AsyncClose will close it. Therefore call client.AsyncClose().