Mass Dispose, better way? - c#

So i am currently disposing many objects when i close my form. Even though it probably disposes it automatically. But still i prefer to follow the "rules" in disposing, hopefully it will stick and help prevent mistakes.
So here is how i currently dispose, which works.
if (connect == true)
{
Waloop.Dispose();
connect = false;
UninitializeCall();
DropCall();
}
if (KeySend.Checked || KeyReceive.Checked)
{
m_mouseListener.Dispose();
k_listener.Dispose();
}
if (NAudio.Wave.AsioOut.isSupported())
{
Aut.Dispose();
}
if (Wasout != null)
{
Wasout.Dispose();
}
if (SendStream != null)
{
SendStream.Dispose();
}
So basically, the first is if a bool is true, meaning if it isn´t those can be ignore, as they haven´t been made i think.
The others are just ways for me to dispose if it´s there. but it´s not a very good way, i would like to have it in 1 big function, meaning.
Dispose if it´s NOT disposed. or something.
I know that many of them has the "isdisposed" bool, so it should be possible if i can check every object, and dispose if it´s false.

How about a helper method which takes objects which implement IDisposable as params?
void DisposeAll(params IDisposable[] disposables)
{
foreach (IDisposable id in disposables)
{
if (id != null) id.Dispose();
}
}
When you want to dispose multiple objects, call the method with whatever objects you want to dispose.
this.DisposeAll(Wasout, SendStream, m_mouseListener, k_listener);
If you want to avoid calling them explicity, then store them all in a List<>:
private List<IDisposable> _disposables;
void DisposeAll() {
foreach(IDisposable id in _disposables) {
if(id != null) id.Dispose();
}
}

You can implement a Disposer class, that will do the work for you, along these lines:
public class Disposer
{
private List<IDisposable> disposables = new List<IDisposable>();
public void Register(IDisposable item)
{
disposables.Add(item);
}
public void Unregister(IDisposable item)
{
disposables.Remove(item);
}
public void DisposeAll()
{
foreach (IDisposable item in disposables)
{
item.Dispose();
}
disposables.Clear();
}
}
Then, instead of the ugly code in your main class, you can have something like:
public class Main
{
//member field
private Disposer m_disposer;
//constructor
public Main()
{
....
m_disposer = new Disposer();
//register any available disposables
disposer.Register(m_mouseListener);
disposer.Register(k_listener);
}
...
public bool Connect()
{
...
if (isConnected)
{
Waloop = ...
Wasout = ...
// register additional disposables as they are created
disposer.Register(Waloop);
disposer.Register(Wasout);
}
}
...
public void Close()
{
//disposal
disposer.DisposeAll();
}
}

I suggest you use the using statement. So with your code, it would look something like this:
using (WaloopClass Waloop = new WaloopClass())
{
// Some other code here I know nothing about.
connect = false; // Testing the current value of connect is redundant.
UninitializeCall();
DropCall();
}
Note there is now no need to explicitly Dispose Waloop, as it happens automatically at the end of the using statement.
This will help to structure your code, and makes the scope of the Waloop much clearer.

I am going to suppose that the only problem you’re trying to solve is how to write the following in a nicer way:
if (Wasout != null)
Wasout.Dispose();
if (SendStream != null)
SendStream.Dispose();
This is a lot of logic already implemented by the using keyword. using checks that the variable is not null before calling Dispose() for you. Also, using guarantees that thrown exceptions (perhap by Wasout.Dispose()) will not interrupt the attempts to call Dispose() on the other listed objects (such as SendStream). It seems that using was intended to allow management of resources based on scoping rules: using using as an alternative way to write o.Dispose() may be considered an abuse of the language. However, the benefits of using’s behavior and the concision it enables are quite valuable. Thus, I recommend to replace such mass statically-written batches of the “if (o != null) o.Dispose()” with an “empty” using:
using (
IDisposable _Wasout = Wasout,
_SendStream = SendStream)
{}
Note that the order that Dispose() is called in is in reverse of how objects are listed in the using block. This follows the pattern of cleaning up objects in reverse of their instantiation order. (The idea is that an object instantiated later may refer to an object instantiated earlier. E.g., if you are using a ladder to climb a house, you might want to keep the ladder around so that you can climb back down before putting it away—the ladder gets instantiated first and cleaned up last. Uhm, analogies… but, basically, the above is shorthand for nested using. And the unlike objects can be smashed into the same using block by writing the using in terms of IDisposable.)
dotnetfiddle of using managing exceptions.

Related

Determine execution flow with nullchecks to operate components as best as possible

Many times I find myself in the need of checking which type of componenent am I handling to make the corresponding operations.
For example:
bool isFooAType = someGameObject.GetComponent<FooA>() != null;
bool isFooBType = someGameObject.GetComponent<FooB>() != null;
if (isFooAType) {
FooA myFooA = someGameObject.GetComponent<FooA>();
//FooA Operations....
}
if (isFooBType) {
FooA myFooB = someGameObject.GetComponent<FooB>();
//FooB Operations....
}
Is there a more condensed or more elegant way to determine the flow of execution depending on the component type to handle the corresponding operations and even maybe avoid doing GetComponent twice (one to check if its null + get again to operate the component in the code successively)?
As mentioned there is TryGetComponent so you do simply
if (someGameObject.TryGetComponent<FooA>(out var fooA))
{
fooA.DoSomething();
}
if (someGameObject.TryGetComponent<FooB>(out var fooB))
{
fooB.DoSomehtingElse();
}
If this is not available (and only then) e.g. due to older Unity versions rather still make the call ONCE and do
var fooA = someGameObject.GetComponent<FooA>();
var fooB = someGameObject.GetComponent<FooB>();
if (fooA)
{
fooA.DoSomething();
}
if (fooB)
{
fooB.DoSomehtingElse();
}
In general you might want both to be exclusive by using else if.
And in particular if both are basically implementing the same method you would rather use a common base class or interface and have only one single TryGetComponent or GetComponent call.

Disposing of all members in a loop

I have a very large project with multiple pages, where each page has many IDisposable members.
I'm trying to figure out a way to dispose all the IDisposable members in a loop so I won't have to type x1.Dispose(); x2.Dispose; ... xn.Dispose on each class.
Is there a way to do this?
Thank you.
Sure, just make sure that you create a list to hold them, and a try finally block to protect yourself from leaking them.
// List for holding your disposable types
var connectionList = new List<IDisposable>();
try
{
// Instantiate your page states, this may be need to be done at a high level
// These additions are over simplified, as there will be nested calls
// building this list, in other words these will more than likely take place in methods
connectionList.Add(x1);
connectionList.Add(x2);
connectionList.Add(x3);
}
finally
{
foreach(IDisposable disposable in connectionList)
{
try
{
disposable.Dispose();
}
catch(Exception Ex)
{
// Log any error? This must be caught in order to prevent
// leaking the disposable resources in the rest of the list
}
}
}
However, this approach is not always ideal. The nature of the nested calls will get complicated and require the call to be so far up in the architecture of your program that you may want to consider just locally handling these resources.
Moreover, this approach critically fails in the scenario where these Disposable resources are intensive and need to be immediately released. While you can do this, i.e. track your Disposable elements and then do it all at once, it is best to try to get the object lifetime as short as possible for managed resources like this.
Whatever you do, ensure not to leak the Disposable resource. If these are connection threads, and they are inactive for some period of time, it may also be wise to simply look at their state and then re-use them in different places instead of letting them hang around.
Using reflection (not tested):
public static void DisposeAllMembersWithReflection(object target)
{
if (target == null) return;
// get all fields, you can change it to GetProperties() or GetMembers()
var fields = target.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic);
// get all fields that implement IDisposable
var disposables = fields.Where(x => x.FieldType.GetInterfaces().Contains(typeof(IDisposable)));
foreach (var disposableField in disposables)
{
var value = (IDisposable)disposableField.GetValue(target);
if (value != null)
value.Dispose();
}
}
Create method which will dispose all your disposable objects:
public void DisposeAll()
{
x1.Dispose();
x2.Dispose();
x3.Dispose();
. . .
}
and call it wherever you need it.

Break out of parent function?

public static void CacheUncachedMessageIDs(List<int> messageIDs)
{
var uncachedRecordIDs = LocalCacheController.GetUncachedRecordIDs<PrivateMessage>(messageIDs);
if (!uncachedRecordIDs.Any()) return;
using (var db = new DBContext())
{
.....
}
}
The above method is repeated regularly throughout the project (except with different generics passed in). I'm looking to avoid repeated usages of the if (!uncachedRecordIDs.Any()) return; lines.
In short, is it possible to make the LocalCacheController.GetUncachedRecordIDs return the CacheUncachedMessageIDs method?
This will guarantee a new data context is not created unless it needs to be (stops accidentally forgetting to add the return line in the parent method).
It is not possible for a nested method to return from parent method.
You can do some unhandled Exception inside GetUncachedRecordIDs, that will do the trick, but it is not supposed to do this, so it creates confusion. Moreover, it is very slow.
Another not suggested mechanic is to use some goto magic. This also generates confusion because goto allows unexpected behaviour in program execution flow.
Your best bet would be to return a Result object with simple bool HasUncachedRecordIDs field and then check it. If it passes, then return. This solution solves the problem of calling a method, which is Any() in this case.
var uncachedRecordIDsResult = LocalCacheController.GetUncachedRecordIDs<PrivateMessage>(messageIDs);
if(uncachedRecordIDsResult.HasUncachedRecordIDs) return;
My reasoning for lack of this feature in the language is that calling GetUncachedRecordIDs in basically any function would unexpectedly end that parent function, without warning. Also, it would intertwine closely both functions, and best programming practices involve loose coupling of classes and methods.
You could pass an Action to your GetUncachedRecordIDs method which you only invoke if you need to. Rough sketch of the idea:
// LocalCacheController
void GetUncachedRecordIDs<T>(List<int> messageIDs, Action<List<int>> action)
{
// ...
if (!cached) {
action(recordIds);
}
}
// ...
public static void CacheUncachedMessageIDs(List<int> messageIDs)
{
LocalCacheController.GetUncachedRecordIDs<PrivateMessage>(messageIDs, uncachedRecordIDs => {
using (var db = new DBContext())
{
// ...
}
});
}

Detecting deadlocks WinForms application

we have a quite large winforms desktop application. Our application runs every once in a while into a deadlock and we are not sure how this happens.
We do know that this is caused by a locking operation. So we have quite a lot code parts like this:
lock (_someObj)
DoThreadSaveOperation();
Our approach to be able to detect what the deadlock was caused by we want to convert all those lock operations into something like this:
bool lockTaken = false;
var temp = _someObj;
try {
System.Threading.Monitor.TryEnter(temp, 1000, ref lockTaken);
if (!lockTaken)
{
// log "can't get lock, maybe deadlock, print stacktrace
}
DoThreadSaveOperation();
}
finally {
System.Threading.Monitor.Exit(temp);
}
This "lock service" should be at a central position. The problem is that it then has to be called like this:
LockService.RunWithLock(object objToLock, Action methodToRun);
That would mean that we had to create a delegate function for each statement which is executed after a lock.
Since this would be a lot of refactoring, I thought I'd give a try on stackoverflow if you guys have a better/good idea about this and also ask for your opinion.
Thanks for you help =)
Since the existing lock functionality closely models a using statement, I suggest that you wrap up your logic in a class that implements IDisposable.
The class's constructor would attempt to get the lock, and if it failed to get the lock you could either throw an exception or log it. The Dispose() method would release the lock.
You would use it in a using statement so it will be robust in the face of exceptions.
So something like this:
public sealed class Locker: IDisposable
{
readonly object _lockObject;
readonly bool _wasLockAcquired;
public Locker(object lockObject, TimeSpan timeout)
{
_lockObject = lockObject;
Monitor.TryEnter(_lockObject, timeout, ref _wasLockAcquired);
// Throw if lock wasn't acquired?
}
public bool WasLockAquired
{
get
{
return _wasLockAcquired;
}
}
public void Dispose()
{
if (_wasLockAcquired)
Monitor.Exit(_lockObject);
}
}
Which you could use like this:
using (var locker = new Locker(someObj, TimeSpan.FromSeconds(1)))
{
if (locker.WasLockAquired)
{
// ...
}
}
Which I think will help to minimise your code changes.

Static and Generic working together .NET

I have this code:
public class EntityMapper<T> where T : IMappingStrategy, new()
{
private static T currentStrategy;
public static T CurrentStrategy
{
get
{
if (currentStrategy == null)
currentStrategy = new T();
return currentStrategy;
}
}
}
Then:
public static void Main()
{
EntityMapper<ServerMappingStrategy>.CurrentStrategy.ToString();
EntityMapper<ClientMappingStrategy>.CurrentStrategy.ToString();
EntityMapper<ServerMappingStrategy>.CurrentStrategy.ToString();
}
Well, the question is:
Why when i'm debugging i can see that the constructor of ServerBussinessMappingStrategy is called only once time?
This work well, but i undertand why always EntityMapper return the correct instance that i need, only instantiating once time the ServerMappingStrategy class.
Regards!
PD: Sorry my english jeje ;)
The static field is persisted for the duration of your AppDomain, and it is cached when first created:
public static T CurrentStrategy
{
get
{
if (currentStrategy == null) // <====== first use detected
currentStrategy = new T(); // <==== so create new and cache it
return currentStrategy; // <=========== return cached value
}
}
Actually, there is an edge case when it could run twice (or more), but it is unlikely.
This is a pretty common pattern for deferred initialization, and is used pretty much identically in a number of places in the BCL. Note that if it had to happen at most once, it would need either synchronization (lock etc) or something like a nested class with a static initializer.
Normally, it will only get called once. That is, unless you have a race condition.
Let's say two threads execute this statement the same time:
EntityMapper<ServerMappingStrategy>.CurrentStrategy.ToString();
Let's say thread A will run up until currentStrategy == null but gets paused before new T() when Windows suddenly gives control to thread B which then makes the comparison again, currentStrategy is still null, invokes the constructor and assigns the new instance to currentStrategy. Then, at some point, Windows gives the control back to thread A that calls the constructor again. This is important because normally static members are (sort of) expected to be thread safe. So if I were you, I would wrap that bit into a lock clause.
P.S. this snippet won't compile as T might be a struct that cannot be a null. Instead of comparing to null, compare to default(T) or specify that T has to be a class.

Categories

Resources