Okay, the situation is as following:
I have one client that has 2 settings: ConnectionState and ConnectionSollState, both the same enumerable (TypeConnectionState), they store the actual state of the client connection and the state the connection should be. On every combination of the to, something different should happen, like when ConnectionState is "Connected" but ConnectionSollState is "Closed" -> Teardown the client. So I have like 4 possibilities that I have to check. Now every client can handle an infinite number of sessions, and every session has also a state (StreamState & StreamSollState), those states can have 6 options in enumerable.
From now on, I'm making like 20 switch-conditions and my code looks really messy, I'm doing something wrong every 5 minutes while coding. Is there an easier way to handle a situation like this? (if/else) would make things waaay worse.
Example:
private void RTSPWorker() {
try {
byte[] buffer = new byte[2048];
while (!mb_RTSPWorkerAbbort) {
// Call TransportWD
Thread.Sleep(100 * mi_ConnectionTimeOut);
// Check ConnectionSollState
switch(ConnectionSollState) {
case TypeConnectionState.Connected:
// ConnectionSollState = Connected, check ConnectionState
switch(ConnectionState) {
case TypeConnectionState.Connected:
// ConnectionState is connected, keep-alive!
if(GET_PARAMETER() == null) {
DESCRIBE();
}
// Check streams too
foreach (cRTSPStream oStream in mo_StreamDict.Values) {
// Check StreamSollState
switch(oStream.RTSPStreamSollState) {
case cRTSPStream.TypeRTSPStreamState.Play:
// SollState is PLAY, check State
switch(oStream.RTSPStreamState) {
case cRTSPStream.TypeRTSPStreamState.Play:
//Stream is alive, keep-alive!
if (oStream.PLAY() == null) { oStream.DESCRIBE(); } break;
case cRTSPStream.TypeRTSPStreamState.Closed:
// Reinitialise.
if (oStream.SETUP() != null) { oStream.PLAY(); } break;
default:
// Default, send play.
oStream.PLAY(); break;
}
break;
case cRTSPStream.TypeRTSPStreamState.Pause:
// SollState is on pause, check State
switch(oStream.RTSPStreamState) {
case cRTSPStream.TypeRTSPStreamState.Closed:
// Reinitialise.
if (oStream.SETUP() != null) { oStream.PLAY(); } break;
default:
oStream.PAUSE();
break;
}
break;
case cRTSPStream.TypeRTSPStreamState.Closed:
// SollState is closed, check State
switch(oStream.RTSPStreamState) {
case cRTSPStream.TypeRTSPStreamState.Closed:
// Is closed, do nothing
break;
default:
// Default teardown, remove session
oStream.TEARDOWN();
this.RemoveRTSPSession(oStream);
break;
}
default:
// Default, what do?
break;
}
}
break;
case TypeConnectionState.Closed:
// ConnectionState should be connected, re-connect!
while(Connect() != true) {
// Sleep for 200ms, try again
Thread.Sleep(200);
}
break;
default:
// TODO anything else
break;
}
break;
case TypeConnectionState.Closed:
// Check ConnectionState
switch(ConnectionState) {
case TypeConnectionState.Connected:
// Is connected, should be closed. Close connection & clean up!
Close(null);
break;
default:
// Anything other than Connected, do nothing.
break;
}
break;
default:
break;
}
}
} catch {
}
}
Holy smokes, Batman, that is some incomprehensible code you have there. Here are some tips that might improve your situation. I must add that these tips are somewhat biased as they prefer a personal coding style:
List<Tuple<T1,T2,T etc..>>
construction.Ex:
var truthTable = List<Tuple<NavigationTab, Role, Action>>
{
new Tuple<NavigationTab, Role, Action>(NavigationTab.Users, Role.UsersAdministration, MVC.Administration.Users.Index()),
new Tuple<NavigationTab, Role, Action>(NavigationTab.Users, Role.RolesAdministration, MVC.Administration.Roles.Index()),
new Tuple<NavigationTab, Role, Action>(NavigationTab.Products, Role.ProductsAdministration, MVC.Administration.Products.Index()),
}
Better object orientation is generally considered the best alternative to switch statements. For instance, you can use polymorphism instead of switch statements and do the following:
try {
byte[] buffer = new byte[2048];
while (!mb_RTSPWorkerAbbort) {
Thread.Sleep(100 * mi_ConnectionTimeOut);
worker.DoWork();
}
} catch (Exception ex) {
Trace.WriteLine(ex);
}
As state changes you can instantiate different types of worker classes that implement DoWork
differently. One might be:
while(Connect() != true) {
// Sleep for 200ms, try again
Thread.Sleep(200);
}
Of course, I don't necessarily think you should do it exactly that way. The only thing I have to go by is the code you posted--so, there's likely much better ways of implementing different behaviour.
This would be very similar to the Specification Pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With