How do I dispose this code properly? - c#

I have a quite large project which I try to keep as clean and tidy as possible. When I run the code analyzer in Visual Studio I get a reliability error which I find quite annoying. I'd really like to learn how to work around it. Here is a simplified example of what I am doing.
Here is the warning.
Warning 1 CA2000 : Microsoft.Reliability : In method 'MyExampleClassForStackOverflow.AddFeed(string)', call System.IDisposable.Dispose on object 'new FeedClassExamle()' before all references to it are out of scope.
Here is my example code:
class MyExampleClassForStackOverflow : IDisposable
{
public ConcurrentDictionary<string, FeedClassExamle> Feeds { get; set; }
public void AddFeed(string id)
{
//The warning is coming from this code block.
//In the full code, the feed classes collects data on a specific
//interval and feeds them back using events.
//I have a bunch of them and they need to be accessible so I
//store them in dictionaries using keys to effeciently find them.
Feeds.TryAdd(id, new FeedClassExamle());
Feeds[id].Start();
}
public void Dispose()
{
foreach (var item in Feeds)
item.Value.Dispose();
}
}
class FeedClassExamle : IDisposable
{
public void Start()
{
}
public void Dispose()
{
}
}
In order to test the code, use:
using (var example = new MyExampleClassForStackOverflow())
{
}
Any suggestion would be welcome.

The warning exists because the code analysis tools can't determine whether the object will get disposed correctly. The way your code is written, the object will not in fact get disposed correctly, but fixing the code will likely not eliminate the warning.
Fundamentally, what needs to happen is for every the AddFeed method to ensure that something will call Dispose on every FeedClassExample instance it creates. The best approach is to avoid creating a FeedClassExample instance if one already exists in the dictonary under the present ID. Failing that, the AddFeed method should either dispose of any FeedClassExample it creates but then decides not to store in the dictionary, or else swap with the one that is in the dictionary (I'm not sure what methods ConcurrentDictionary supports to do that) and then Dispose the old one. The essential requirement is that at all times outside the actual execution of AddFeed, the dictionary will hold all instances of FeedClassExample that have been created but not destroyed.
It may be informative to add a destructor in your FeedClassExample class which does nothing except log a message. If you are calling Dispose on that class correctly, the destructor will never execute. If you fail to call Dispose, it will. Thus, if the destructor ever executes, you can know you're doing something wrong.

The object isn't getting Disposed of if TryAdd fails, so try doing this explicitly:
public void AddFeed(string id)
{
FeedClassExample fce = new FeedClassExamle();
if (!Feeds.TryAdd(id, fce))
{
fce.Dispose();
}
Feeds[id].Start();
}

Only create the instance if it needs to be added:
if (!Feeds.ContainsKey(id)) {
Feeds.GetOrAdd(id, new FeedClassExamle());
}

Related

How to delete an object on c#?

Is it possible if we delete an object from the class itself? I have a class like below:
Parent Class:
public class ModelBase<T>
{
.....
public void Delete()
{
this = null // <-- it's not works
}
.....
}
Children Class:
public class Company : ModelBase<Company>
{
public string Name;
public Company(string name)
{
Name = name;
}
}
Declaring on UI Layer:
var company = new Company("Company X");
Console.WriteLine(company.Name);
company.Delete();
Console.WriteLine(company.Name); // <-- this should be empty or null
Deleting the object should be on parent class. Is it possible to do that?
No, in C# the garbage collection does the "deleting" for you eventually.
If there`s something inside the class you want to manually dispose like a connection you can use the Disposable Pattern (https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern).
The closest you can come to manually deleting the object is forcing the garbage collector to collect with GC.Collect (https://msdn.microsoft.com/en-us/library/xe0c2357(v=vs.110).aspx).
Obviously setting this to null inside Delete function has not effect outside of the function (if it ever compile).
Destroying an object from itself is also very dangerous as you would have to be sure that no code afterward would access that object (or the caller stack). IN fact, in C#, the idea does not make more sense as it is garbage collected which imply that if you are inside a member function, then you have at least one reference to the object in which case it would never be garbage collected at that point anyway.
Also assuming that the object company was destroyed (and company set to null), you would get a null pointer exception when calling .Name.
Assuming that company object is not disposable (does not implement IDisposable), then your code should look like:
var company = new Company("Company X");
Console.WriteLine(company.Name);
company = null;
Console.WriteLine(company?.Name); // <-- this should be empty or null
Well, we assume that real code is somewhat more complex than that as otherwise you could simply replace last line by:
Console.WriteLine();
However if you company object implement IDisposable, then usually you should use the using keyword if which case setting the object to null would not make sense.
using (var company = new Company("Company X"))
{
Console.WriteLine(company.Name);
}
Console.WriteLine();
Your Delete function is really a bad idea and clearly show a lack of understanding of C#.
If you want to know if an object has been destroyed, you could use WeekReference. As an example, it can be used for a cache. See reference documentation for more information: https://msdn.microsoft.com/en-us/library/system.weakreference(v=vs.110).aspx.
Your whole code make little sense. If you have only one variable, then it is trivial for a decent programmer to know when the object is alive. If you have multiple objects, then you should use a collection (for ex. List<Company>) in which case, you would obviously remove a company from the collection if you don't want it anymore and then when you use that collection, you would not see it anyway.
Alternatively for complexe cases, you might use a dictionary, a set or a flag to remember if you should process a given object. This might be useful for example when iterating a collection as usually you should not modifying while you are enumerating its items.

How to secure delegate instance reference

In the perspective of callbacks, I am facing a strange situation when I knew that myDelegate.Target contains the reference to the class whose method it contains. (I searched it on SO, however I excuse if I missed some thread already answering this)
For example
public delegate void TravePlanDelegate();
public class Traveller
{
//Papa is planing a tour, along with Mama
public void Planner()
{
//Asking me (delegate) to hold a letter about PlanA's detail
TravelPlanDelegate myPlan = PlanA;
//Sending me to TravelAgency office with letter
new TravelAgency().ExecuteTravelPlan(myPlan);
}
public void PlanA()
{
//Papa's open plan with Mama
Console.WriteLine("First Berline, then New Yark and finally Lahore");
}
public void PlanB()
{
//Papa's secret plan
Console.WriteLine("First Dubai, and then Lahore");
}
}
public class TravelAgency
{
public void ExecuteTravelPlan(TravePlanDelegate tp)
{
Traveller traveller = (Traveller)tp.Target;
//Here it should execute plan
//tp.Target - A reference to Traveler class, which can lead travel
//agency to Papa's secret plan (And exposes it to Mama)
}
}
In this example, TravelAgency can get information from delegate about papa's secret plan too. Did I get delegate concept properly or missing something?
Your assumption is correct. Unfortunately, however you try to "encapsulate" your object- there must always be a reference to it somewhere, otherwise it would be impossible to invoke it's instance method.
As some kind of counter measure, you can proxy the method invocation to a lambda expression:
TravelPlanDelegate myPlan = (args) =>PlanA(args);
This makes it less likely that any rogue code will attempt to carry out some ill intended operations on your code, since knowing how your code looks like in advance will not help it accomplish a thing.
Note that this does not ensure a thing, since the produced delegate still has a Target property to an object which holds a reference to yours.
Crackers which are smart enough can still apply reflection to the generated class and obtain a reference to your object.
Conclusion:
Only consume code you trust - it is not much of a problem in today's Open Source driven world.

Don't understand the using of IDisposable

Would someone explain the following C# code a little bit for me?
I do have knowledge of the normal usage of IDisposable. But I don't understand the following code. The instantiate of new LogLog.LogReceivedAdapter(configurationMessages) looks like have nothing to do with the code block within keyword using. How does statement InternalConfigure(repository, configFile) eventually update variable configurationMessages?
BTW, the code piece was grabbed from log4net XmlConfigurator.cs#508
static public ICollection Configure(ILoggerRepository repository, FileInfo configFile)
{
ArrayList configurationMessages = new ArrayList();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
InternalConfigure(repository, configFile);
}
repository.ConfigurationMessages = configurationMessages;
return configurationMessages;
}
I do not know that exact code, but it may look like the following:
LogLog registers configurationMessages in some static class (let's call it Log) upon construction;
InternalConfigure uses that static class (and in effect configurationMessages are filled up)
The Dispose() method of LogLog class removes the adapter from the Log class.
The part you presented requires heavy guessing, but I believe, that this is the case.
I believe the constructor of LogReceivedAdapter is an answer.
public LogReceivedAdapter(IList items)
{
this.items = items;
handler = new LogReceivedEventHandler(LogLog_LogReceived);
LogReceived += handler;
}
As you can see it does some magic behind, thus - even though there's no direct reference to newly created instance in your code - it might have some sense :)
C# treats classes that implement IDisposable in one specific way: it calls Dispose() at the moment when the code reaches the closing bracket of the "using" block where the object was created.
Look at Dispose() method of the LogLog.LogReceivedAdapter. The code ensures, that this method is called.

Using Wrapper objects to Properly clean up excel interop objects

All of these questions:
Excel 2007 Hangs When Closing via .NET
How to properly clean up Excel interop objects in C#
How to properly clean up interop objects in C#
struggle with the problem that C# does not release the Excel COM objects properly after using them. There are mainly two directions of working around this issue:
Kill the Excel process when Excel is not used anymore.
Take care to explicitly assign each COM object used to a variable first and to guarantee that eventually, Marshal.ReleaseComObject is executed on each.
Some have stated that 2 is too tedious and there is always some uncertainty whether you forget to stick to this rule at some places in the code. Still 1 seems dirty and error-prone to me, also I guess that in a restricted environment trying to kill a process could raise a security error.
So I've been thinking about solving 2 by creating another proxy object model which mimics the Excel object model (for me, it would suffice to implement the objects I actually need). The principle would look as follows:
Each Excel Interop class has its proxy which wraps an object of that class.
The proxy releases the COM object in its finalizer.
The proxy mimics the interface of the Interop class.
Any methods that originally returned a COM object are changed to return a proxy instead. The other methods simply delegate the implementation to the inner COM object.
Example:
public class Application
{
private Microsoft.Office.Interop.Excel.Application innerApplication
= new Microsoft.Office.Interop.Excel.Application innerApplication();
~Application()
{
Marshal.ReleaseCOMObject(innerApplication);
innerApplication = null;
}
public Workbooks Workbooks
{
get { return new Workbooks(innerApplication.Workbooks); }
}
}
public class Workbooks
{
private Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks;
Workbooks(Microsoft.Office.Interop.Excel.Workbooks innerWorkbooks)
{
this.innerWorkbooks = innerWorkbooks;
}
~Workbooks()
{
Marshal.ReleaseCOMObject(innerWorkbooks);
innerWorkbooks = null;
}
}
My questions to you are in particular:
Who finds this a bad idea and why?
Who finds this a gread idea? If so, why hasn't anybody implemented/published such a model yet? Is it only due to the effort, or am I missing a killing problem with that idea?
Is it impossible/bad/error-prone to do the ReleaseCOMObject in the finalizer? (I've only seen proposals to put it in a Dispose() rather than in a finalizer - why?)
If the approach makes sense, any suggestions to improve it?
Is it impossible/bad/dangerous to do the ReleaseCOMObject in the destructor? (I've only seen proposals to put it in a Dispose() rather than in a destructor - why?)
It is recommended not to put your clean up code in the finalizer because unlike the destructor in C++ it is not called deterministically. It might be called shortly after the object goes out of scope. It might take an hour. It might never be called. In general if you want to dispose unmanaged objects you should use the IDisposable pattern and not the finalizer.
This solution that you linked to attempts to work around that problem by explicitly calling the garbage collector and waiting for the finalizers to complete. This is really not recommended in general but for this particular situation some people consider it to be an acceptable solution due to the difficulty of keeping track of all the temporary unmanaged objects that get created. But explicitly cleaning up is the proper way of doing it. However given the difficulty of doing so, this "hack" may be acceptable. Note that this solution is probably better than the idea you proposed.
If instead you want to try to explicitly clean up, the "don't use two dots with COM objects" guideline will help you to remember to keep a reference to every object you create so that you can clean them up when you're done.
We use the LifetimeScope class that was described in the MSDN magazine. Using it properly cleans up objects and has worked great with our Excel exports. The code can be downloaded here and also contains the magazine article:
http://lifetimescope.codeplex.com/SourceControl/changeset/changes/1266
Look at my project MS Office for .NET. There is solved problem with referencich wrapper objects and native objects via native VB.NET late-binding ability.
What I'd do:
class ScopedCleanup<T> : IDisposable where T : class
{
readonly Action<T> cleanup;
public ScopedCleanup(T o, Action<T> cleanup)
{
this.Object = o;
this.cleanup = cleanup;
}
public T Object { get; private set; }
#region IDisposable Members
public void Dispose()
{
if (Object != null)
{
if(cleanup != null)
cleanup(Object);
Object = null;
GC.SuppressFinalize(this);
}
}
#endregion
~ScopedCleanup() { Dispose(); }
}
static ScopedCleanup<T> CleanupObject<T>(T o, Action<T> cleanup) where T : class
{
return new ScopedCleanup<T>(o, cleanup);
}
static ScopedCleanup<ComType> CleanupComObject<ComType>(ComType comObject, Action<ComType> actionBeforeRelease) where ComType : class
{
return
CleanupObject(
comObject,
o =>
{
if(actionBeforeRelease != null)
actionBeforeRelease(o);
Marshal.ReleaseComObject(o);
}
);
}
static ScopedCleanup<ComType> CleanupComObject<ComType>(ComType comObject) where ComType : class
{
return CleanupComObject(comObject, null);
}
Usage case. Note the call to Quit, which seems to be necessary to make the process end:
using (var excel = CleanupComObject(new Excel.Application(), o => o.Quit()))
using (var workbooks = CleanupComObject(excel.Object.Workbooks))
{
...
}
For what it's worth, the Excel Refresh Service on codeplex uses this logic:
public static void UsingCOM<T>(T reference, Action<T> doThis) where T : class
{
if (reference == null) return;
try
{
doThis(reference);
}
finally
{
Marshal.ReleaseComObject(reference);
}
}

How do I determine who is the creator of an object

I have a class that is called regularly by several objects.
I would like to include information in any exceptions as who the creater of the object is.
What are my options?
"Who" refers to an object or class
Store a stacktrace when the constructor is called. This is similar to what SlimDX does in debug builds.
I might be missing something, but I am pretty sure that the only way you can do it, is by manually passing this information, fe. in constructor of your object.
Edit : If this is what you were looking for? :
class Creator
{
public string Name { get; private set; }
public Creator(string name)
{
Name = name;
}
}
class Foo
{
readonly Creator creator;
public Foo(Creator creator)
{
this.creator = creator;
}
public void DoSth()
{
throw new Exception("Unhandled exception. My creator is " + creator.Name);
}
}
public static void Main()
{
Foo f = new Foo(new Creator("c1"));
f.DoSth();
}
If it's only for debugging purposes then add a local string field to the class and assign Environment.StackTrace to it in the class constructor. Then you can include the information in the exceptions as well.
One choice would be to put a "parent" reference into the object:
MyObject myObj = new MyObject(this);
and then use that.
You can try to gather some information from the stack trace in the constructor of your object. You can get the stack frames StackTrace.GetFrames. Then you can walk the stack and try to get the type that a method belongs. If that type is different than the type of your object, you stop walking and store that type information within your object. Then when an exception occurs, you can include that information along with the exception.
Note that this will increase the cost of instantiating your object. So you should consider that and may be put in a mechanism to enable/disable it or include that piece of code only in the debug build.
The question is slightly ambiguous; it really depends what you want. Is this debug information for debug builds, or is it something you will always keep around?
If it's just debug cruft that will be removed in the released product, I'd suggest doing something like this to reduce the pollution of your class(es):
Move the creation into a factory and put the stack inspection code there. This way, the created class doesn't need to care about the stack frame stuff; it is hidden away in the factory.
You can then inject the information via a property setter if you don't mind a little pollution or you could have the factory update a list of created instances + associated creation information for each instance. You can then query this list til your heart is content. Finally, in the release build, you can remove all of this functionality with a couple of #ifdefs.
I'd recommend using the StackTrace object and/or it's GetFrame method. I haven't tried it but it should do what you need it to do w/o having to change every instantiation of the object (assuming you're not using a Factory).
I would imagine something similar to this would work.
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
Also note that this appears to be "not quite" a duplicate, but it's close to the question linked above.
Something like this could work to get the calling type:
public class Foo
{
private Type ParentAtCreation = null;
public Foo()
{
ParentAtCreation = (new StackTrace())
.GetFrame(1)
.GetMethod()
.DeclaringType;
}
}
You can use overloaded constructor to that class and a global variable to store that object you receive in that overloaded constructor
e.g if you want an object of class in winforms when you invoke the object to be created you use a overloaded constructor that receives an object of a form
and in the constructor you use this object to store its value in global variable like
When you declare the object as in this case i use a form to open using my currently running form then
Admin_Login ad = new Admin_Login(Enrol, this);
ad.Show();
this.Visible = false;
and make the current form not visible to invoke it again when i want it. I cant dispose it as its the parent of the new form now
and in Admin_Login form i have an overloaded constructor
public Admin_Login(string Enrol,Form parent)
{
Enrollment = Enrol;
Parent = parent;
InitializeComponent();
}
where Parent is my global variable of Form
B.O.L
I'm surprised no one else has said this yet, even as a caveat to their own solution, so I will: this is generally a bad idea, and if you find yourself needing to do it, that's usually a huge indicator that something is very wrong with your design. If you go down this route to solve your problem, you will end up causing far larger issues down the road. Best to take 2 steps back and fix the design that is making this necessary.

Categories

Resources