Disposing a HtmlControl - visual-studio-2010

On the advice of Code Analysis in VS to call Dispose on an object (which I wasn't previuosly) I ended up with a method containing this:
using (var favicon = new HtmlLink
{
Href = "~/templates/default/images/cc_favicon.ico"
})
{
favicon.Attributes.Add("rel", "shortcut icon");
Header.Controls.Add(favicon);
}
This confused me slightly, if I dispose this object after adding it to the Controls collection is that such a good idea?
How does this still work? Is it because the Controls.Add method disposes the object after use as opposed to holding on to it?

I would say that this code shouldn't work but if you say it's working then the only things I can think of are:
Header.Controls.Add add a copy of the object so there is no problem disposing the original.
The Dispose method does not clean anything that is used later.
Hope this helps.

If a method on favicon is called that uses any of the unmanaged resources it will give exception.
From msdn:
You can instantiate the resource object and then pass the variable to
the using statement, but this is not a best practice. In this case,
the object remains in scope after control leaves the using block even
though it will probably no longer have access to its unmanaged
resources. In other words, it will no longer be fully initialized. If
you try to use the object outside the using block, you risk causing an
exception to be thrown. For this reason, it is generally better to
instantiate the object in the using statement and limit its scope to
the using block.
using statement msdn

I assume that you code analysis gave you CA2000: Dispose objects before losing scope before you changed the code. The problem is that you shouldn't dispose your object because you want to use it even after returning from the method (it has been added to a collection).
You can either suppress the message using the SuppressMessage attribute or you can rewrite you code to be really paranoid:
var favicon = new HtmlLink { Href = "~/templates/default/images/cc_favicon.ico" };
try {
favicon.Attributes.Add("rel", "shortcut icon");
}
catch {
favicon.Dispose();
throw;
}
Header.Controls.Add(favicon);
The normal flow of this code adds favicon to the collection that is then responsible for disposing it. However, the abnormal flow where favicon.Attributes.Add throws an exception will dispose favicon before propagating the exception.
In most case, because the garbage collector will do its job eventually, you don't need the paranoid version of the code.

Related

How to override class files (asm.ClassWriter.getCommonSuperClass)?

What I am trying to do?
I am trying to add try/catch block in start and end of a particular method.
Why am I overriding asm.ClassWriter.getCommonSuperClass(String class1,String class2)?
I am using flag COMPUTE_FRAMES, and because of that, asm.ClassWriter.getCommonSuperClass() this class is being called and it is trying to load some classes again using class.ForName(), and saying classNotFoundException. I read somewhere to override this method and make sure it gets these two classes loaded. I got hold of Instrumentation object and got all loaded classes, but there are still some classes which are not loaded and this method throws NullPointer Exception..
Any suggesstions how to override it?
EDITED THE QUESTION BASED ON BELOW RESPONSE
What I understand here is :
1. There is no need to use COMPUTE_FRAMES instead of COMPUTE_MAXS, if I am trying to add a try/catch block for method content.
2. If I want to just add try/catch block for method content,(assume jdk8 only) then i just need to write try/catch block ASM part and rest should fall in place.
For a method which is called from a thread:
public void execute()throws IOException{
//some code
}
Below code should add try/catch block and should not give any java verify error?:
private Label startFinally = new Label();
public void visitMaxs(int maxStack, int maxLocals) {
Label endFinally = new Label();
visitTryCatchBlock(startFinally, endFinally, endFinally, "java/lang/Exception");
visitLabel(endFinally);
visitFrame(F_NEW, 0, null, 1, new Object[]{"java/lang/Exception"});
visitVarInsn(ASTORE, 1);
visitVarInsn(ALOAD, 1);
visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace", "()V", false);
visitInsn(RETURN);
}
public void visitCode() {
mv.visitLabel(startFinally);
super.visitCode();
}
When you start having to deal with getCommonSuperClass you are entering the very issue that stack map frames were designed to solve. Instead of letting the verifier do such a common superclass search, the frames derived from information available to the compiler should tell which type to assume and verifying the correctness is cheaper than performing this search.
But, of course, if you use a framework like ASM and let it conveniently calculate all these frames from scratch without the information available to the compiler, you end up doing that expensive operation and even have to assist ASM in case the types are not available to a simple Class.forName call (or you want avoid the loading of the classes).
You should note two important things:
You don’t have to load these classes. This method intentionally provides two strings and expect a result string. If you have meta information available that allow you to determine the common super type based on the name, you can use it
When you use Instrumentation to search for the name among all loaded classes, you might miss the class because it might not have been loaded yet. Even worse, you could get the wrong class in a more complex scenario when classes with the same name have been loaded by different ClassLoaders
At this time you should think about whether adhering to the original intent of using the already known information to generate the right frame is an option. When you instrument a class of a version where stack map frames are mandatory, all frames beside the one required for your exception handler are already present. And for older class files without frames, you don’t need to compute them anyway.
When you chain a ClassReader with a ClassWriter it will not only replicate members and instructions but also the stack map frames, unless you specify COMPUTE_FRAMES which causes ASM to drop all visited frames and recalculate them from scratch. So the first thing to do is to change COMPUTE_FRAMES back to COMPUTE_MAXS and then insert visitFrame calls as needed.
For covering the entire method with one exception handler, we need exactly one frame, for the entry of the handler (assuming there are no branches inside the handler itself). We already know that the operand stack consist of a sole reference to the exception itself—that’s always the case for exception handlers. Since the guarded code spans the entire method, no additional local variables introduced inside the method are available, so only this (if the method is not static) and the parameters are available—unless the method’s code reuses them for other purposes (ordinary Java code usually doesn’t). But the good news is, you don’t have to deal with them unless you want to use them.
So let’s assume we want to cover the entire method with an exception handler which will catch the exception, print its stack trace and return (assuming void). Then, we don’t need any local variables and the entire code, applied after completely visiting the original code, looks like:
Label endFinally = new Label();
visitTryCatchBlock(startFinally, endFinally, endFinally, "java/lang/Exception");
visitLabel(endFinally);
visitFrame(F_NEW, 0, null, 1, new Object[]{"java/lang/Exception"});
visitVarInsn(ASTORE, 1);
visitVarInsn(ALOAD, 1);
visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace", "()V", false);
visitInsn(RETURN);
The logic is
visitFrame(F_NEW, // not derived from a previous frame
0, null, // no local variables
1, new Object[]{"java/lang/Exception"} // one exception on the stack
);
Of course, the type of the exception on the stack must match the type of the visitTryCatchBlock or be a super type of it. Note that the local variable we’re going to introduce after entering the handler is irrelevant. If you want to re-throw instead of returning, just replace
visitInsn(RETURN);
with
visitVarInsn(ALOAD, 1);
visitInsn(ATHROW);
and the logic regarding the stack map frame doesn’t change.

GetFunctionPointerForDelegate and pin pointer

Hi this is in regard to some code given in C++ CLI i action which i have trouble understanding.The code is given below
delegate bool EnumWindowsDelegateProc(
IntPtr hwnd,IntPtr lParam);
ref class WindowEnumerator
{
private:
EnumWindowsDelegateProc^ _WindowFound;
public:
WindowEnumerator(EnumWindowsDelegateProc^ handler)
{
_WindowFound = handler;
}
void Init()
{
pin_ptr<EnumWindowsDelegateProc^> tmp = &_WindowFound;
EnumWindows((WNDENUMPROC)
Marshal::GetFunctionPointerForDelegate(
_WindowFound).ToPointer(), 0);
}
};
In the above code _WindowFound has been pinned so GC wont moove it.The Question is
Isn't tmp only valid inside Int() thus _WindowFound pinned only
during call to Int() ?
If thats the case Isn't there a chance the delegate location in
memory might change at the time EnumWindows calls it as a function
pointer?
A pin_ptr<> automatically unpins, RAII-style, when code execution leaves the block that it is declared it. So it will be pinned for the entire body of the Init() method in your code. So your 2 bullet does not apply.
It is notable that the code is in not infact correct. It works, but by accident. Marshal.GetFunctionPointerForDelegate() invokes the stub compiler to auto-generate the native code that's needed to allow the native code to invoke the delegate target. The lifetime of that stub is controlled by the lifetime of the delegate object. In other words, as soon as the delegate object gets garbage collected, the stub will be destroyed as well.
Pinning the delegate object does not in any way affect the stub. It is already unmovable, the GC never moves code. It works by accident because pinning an object requires creating an extra GC handle for the object (GCHandle::Alloc), enough to prevent premature collection.
It doesn't make an enormous difference in this kind of code, EnumWindows() is slow anyway. Not necessarily the case when you call other native code that requires a callback, avoiding pinning should always be a goal in general. All you have to do is let the jitter see a reference to the delegate object beyond the code where it can still be used, like this:
void Init() {
EnumWindows((WNDENUMPROC)
Marshal::GetFunctionPointerForDelegate(
_WindowFound).ToPointer(), 0);
GC::KeepAlive(_WindowFound);
}
Very efficient, GC::KeepAlive() doesn't generate any code, it just tells the jitter to extend the lifetime of the _WIndowFound reference so it can't be collected while EnumWindows() is executing. Even that is overkill in this specific case since somebody is going to have a reference to the WindowEnumerator object in order to retrieve _WindowFound, but better safe than sorry.

Is it possible to catch an "object not initialized" exception in Dynamics AX?

Problem:
I have some code that is failing because an object has not been initialized. The solution for this bug is easy to fix, when detected. However, what surprised me is that my elaborate exception handling didn't catch this exception. That meant the exception wasn't logged or handled, and code following the try catch block was never executed. The try...catch block was outside of the transaction, so there was no issue there.
In this particular case, the exception was inside a batch (RunBaseBatch) job. The job handled several unrelated processing tasks. Once the exception conditions were met, the job terminated, so the other unrelated processing tasks were never called.
Does anyone know if it is possible to catch an "object not initialized" exception in Dynamics AX 2009? I read one post that said it may not be possible to catch certain exceptions in AX, however, I hope that is not the case (reference: https://community.dynamics.com/product/ax/f/33/p/16352/23700.aspx#23700).
Code example:
Here is some simplistic code that recreates the issue:
server static void main(Args args)
{
Array arr;
;
info ("debug: before try...catch");
try
{
// ttsbegin; // enable/disable to test with transactions
// arr = new Array(Types::String); // Enabling this line will prevent the exception
arr.exists(3);
// ttscommit; // enable/disable to test with transactions
}
catch (Exception::Internal) // This exception handler was the Magic Sauce!!
{
info ("debug: catch (Exception::Internal)");
}
catch (Exception::Error)
{
info ("debug: catch (Exception::Error)");
}
catch
{
info ("debug: catch");
}
info ("debug: after try...catch");
}
UPDATE 2013-01-29
I am waiting to accept an answer until this question has been viewed more. Thank you for the answers so far.
I know the example I gave was simplistic. This type of bug is easily fixable when it is known. And defensive programming is always a good idea.
However, in the real world, the code where the bug occurred was very complex. The error occurred several levels deep in an overloaded method of a subclass. It occurred in a specific scenario, when an overloaded method corrupted the protected value of a member variable from the super class. That is where the bug occurred in the code, however, it didn't manifest itself until the super class tried to use the member variable again. The bug was summarily fixed when it was detected and tracked down.
Defensively, yes you could check every protected member variable, every time you use it, but that does start to impact performance, code readability, practicality, etc., which is why languages offer exception handling.
The question here, is how can these type of bugs be caught to make code more robust and bullet-proof? In most development environments (C, C++, C#, or Java for example), a try...catch at a top level could be used to catch, log, and clean up ALL unexpected exceptions. So the code would be able to continue processing with the other unrelated tasks. AX is continuing at some level, because the whole system doesn't come to a grinding halt when this bug occurs. However, the code after the catch in this job is not executing because of what appears to be a deficiency in AX/X++.
I am looking for an innovative solution or work-around, if it exists, to catch the "object not initialized" exception (really ALL exceptions) and to continue processing.
You cannot "catch" it in the traditional sense, but you can avoid it happening. Simply test if the object exists before running anything from it:
if(object)
{
// Exists; Execute statements with object here
}
else
{
// Doesn't exist
}
This works because object will be translated as null if it is not initialized.
(Null == 0) == false
If the object is initialized it will have some value other than null.
(!Null != 0) == true
Hope that helps!
You can, but you shouldn't. A behavior like this is almost certainly a bad design of your code, that will inevitably end in more problems in the future.
You need to make your code defensive to this case, making sure the object is instanciated before using it. Otherwise, you're using the catch code to an expected behavior, wich makes no sense.
EDIT 2013/02/18
In complex scenarios like what you're describing, it's usually very hard to get a solution fully controlled. In AX, try..catch statement is quite simplified and in a very large range of situations is not really needed (unlike Java, C#, ... where is always recommended).
This simplification is nice in almost all situations of AX development, as you don't need to waste time on exception handling. Just let them raise, and the InfoLog will handle them on a simple and reliable way.
The big problem comes where you really need this control... when there is not really a way of force it. I'm not sure if this is really an standard issue or it's espected by the product team to work that way, but this cases are always giving troubles in AX. When you need to catch some specific issue you have to be very creative and deffensive to prevent the exception as catching it will become even more creative...
Hope this helps :)
To elaborate a little, as stated in the post you linked to you cannot catch an Object Not Initialized error. However, you can "fix" the code by adding a simple check before attempting to run functions against a variable that you do not control (for example, if you are requesting an Array type as an argument for a function and you expect the function to be called from outside the class).
try
{
if (arr)
arr.exists(3);
}
The if(arr) statement is enough to skip the processing if the object has not yet been instantiated, effectively bypassing the error. However, this will obviously not throw the error further up the chain. If you really wanted, you could make it throw a different error that can be caught, but obviously that is less than ideal.
In this case, since the RunBaseBatch class may not be something you want to modify it would probably be better to make sure the object that is causing the issue is correctly defined before calling the problem method, and finding these errors in testing.

C++/CLI Resource Management Confusion

I am extremely confused about resource management in C++/CLI. I thought I had a handle (no pun intended) on it, but I stumbled across the auto_gcroot<T> class while looking through header files, which led to a google search, then the better part of day reading documentation, and now confusion. So I figured I'd turn to the community.
My questions concern the difference between auto_handle/stack semantics, and auto_gcroot/gcroot.
auto_handle: My understanding is that this will clean up a managed object created in a managed function. My confusion is that isn't the garbage collector supposed to do that for us? Wasn't that the whole point of managed code? To be more specific:
//Everything that follows is managed code
void WillThisLeak(void)
{
String ^str = gcnew String ^();
//Did I just leak memory? Or will GC clean this up? what if an exception is thrown?
}
void NotGoingToLeak(void)
{
String ^str = gcnew String^();
delete str;
//Guaranteed not to leak, but is this necessary?
}
void AlsoNotGoingToLeak(void)
{
auto_handle<String ^> str = gcnew String^();
//Also Guaranteed not to leak, but is this necessary?
}
void DidntEvenKnowICouldDoThisUntilToday(void)
{
String str();
//Also Guaranteed not to leak, but is this necessary?
}
Now this would make sense to me if it was a replacement for the C# using keyword, and it was only recommended for use with resource-intensive types like Bitmap, but this isnt mentioned anywhere in the docs so im afraid ive been leaking memory this whole time now
auto_gcroot
Can I pass it as an argument to a native function? What will happen on copy?
void function(void)
{
auto_gcroot<Bitmap ^> bmp = //load bitmap from somewhere
manipulateBmp(bmp);
pictureBox.Image = bmp; //Is my Bitmap now disposed of by auto_gcroot?
}
#pragma unmanaged
void maipulateBmp(auto_gcroot<Bitmap ^> bmp)
{
//Do stuff to bmp
//destructor for bmp is now called right? does this call dispose?
}
Would this have worked if I'd used a gcroot instead?
Furthermore, what is the advantage to having auto_handle and auto_gcroot? It seems like they do similar things.
I must be misunderstanding something for this to make so little sense, so a good explanation would be great. Also any guidance regarding the proper use of these types, places where I can go to learn this stuff, and any more good practices/places I can find them would be greatly appreciated.
thanks a lot,
Max
Remember delete called on managed object is akin to calling Dispose in C#. So you are right, that auto_handle lets you do what you would do with the using statement in C#. It ensures that delete gets called at the end of the scope. So, no, you're not leaking managed memory if you don't use auto_handle (the garbage collector takes care of that), you are just failing to call Dispose. there is no need for using auto_handle if the types your dealing with do not implement IDisposable.
gcroot is used when you want to hold on to a managed type inside a native class. You can't just declare a manged type directly in a native type using the hat ^ symbol. You must use a gcroot. This is a "garbage collected root". So, while the gcroot (a native object) lives, the garbage collector cannot collect this object. When the gcroot is destroyed, it lets go of the reference, and the garbage collector is free to collect the object (assuming it has no other references). You declare a free-standing gcroot in a method like you've done above--just use the hat ^ syntax whenever you can.
So when would you use auto_gcroot? It would be used when you need to hold on to a manged type inside a native class AND that managed type happens to implement IDisposable. On destruction of the auto_gcroot, it will do 2 things: call delete on the managed type (think of this as a Dispose call--no memory is freed) and free the reference (so the type can be garbage collected).
Hope it helps!
Some references:
http://msdn.microsoft.com/en-us/library/aa730837(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/481fa11f(v=vs.80).aspx
http://www.codeproject.com/Articles/14520/C-CLI-Library-classes-for-interop-scenarios

Using linq with Sharepoint and disposing of objects

How do i dispose reference to the subWeb in the following query?
using (SPSite spSite = Utility.GetElevatedSite(_rootUrl))
{
from SPWeb web in spSite.AllWebs
where web.ServerRelativeUrl.ToLower() == path
from SPWeb subWeb in web.Webs
select subWeb
}
Do i even need to worry about disposing the subWeb if iam already wraped the spSite in the Using statement?
Edit:
Is it a good idea too call garbage collection in this scenario?
Unfortunately, you do.
The trouble starts from the SPSite.AllWebs property.
The SPWeb.Web property isn't safe either.
Read this very thorough reference of the situations where you need to worry about disposing SharePoint objects.
(I suggest adding this to your SharePoint cheat-sheet).
As a result, I feel the current SharePoint object model can not be safely used with LINQ syntax.
Your code would need a re-write with the various implied loops broken out so that you can explicitly dispose the objects involved.
Edit:
The SPDisposeCheck tool is a command-line console app that will scan your .NET assemblies and warn you of undisposed references based on the above best-practice guidelines. Check it out.
http://code.msdn.microsoft.com/SPDisposeCheck
http://blogs.msdn.com/sharepoint/archive/2008/11/12/announcing-spdisposecheck-tool-for-sharepoint-developers.aspx
The technical answer to your original question is a qualified "No": all SPWeb objects opened from an SPSite are automatically disposed when the SPSite is disposed. However, in practice it is a good idea to dispose an SPWeb as soon as you're done with it to reduce memory pressure, especially when working with code like this that opens several SPWeb objects.
Implementing this dispose-safe behavior for LINQ is actually quite simple in C#. You can find full details in this post, but the short version is that a C# iterator can handle disposal for you. Using my AsSafeEnumerable() extension method, your code is relatively safe written like this:
using (SPSite spSite = Utility.GetElevatedSite(_rootUrl))
{
var sw = from SPWeb web in spSite.AllWebs.AsSafeEnumerable()
where web.ServerRelativeUrl.ToLower() == path
from SPWeb subWeb in web.Webs.AsSafeEnumerable()
select subWeb;
foreach(SPWeb aSubWeb in sw)
{
// Do something
}
}
Now the result of your query, which I've assigned to sw, is a lazy iterator of type IEnumerable<SPWeb>. As you enumerate over that result, each SPWeb will be disposed when the enumerator moves to the next item. This means that it is not safe to use that SPWeb reference, or any SP* object created from it (SPList, etc), outside of your foreach loop. Also sw would not be safe to use outside of that using block because the iterator's SPWebCollections will be tied to the now-disposed SPSite.
That said, code like this that enumerates over all webs (twice!) is extremely expensive. There is almost certainly a more efficient way that this could be implemented, if only by using spSite.AllWebs[path] instead of your from/where.
Regarding garbage collection, these objects require disposal because of unmanaged memory allocated that the GC doesn't even know about.
Finally, a word of caution about your 'GetElevatedSite' utility. If you're using RunWithElevatedPrivileges in your helper method to get your elevated SPSite, there are a number of issues you could run into by returning your SPSite out of that elevated context. If possible, I would suggest using SPSite impersonation instead - my preferred method is described here.

Resources