Say I have this class:
[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
public MyAttribute()
{
// Do stuff
}
~MyAttribute()
{
// When is this called? When the function ends? Whenever the GC feels like?
}
}
Following an example call of GetCustomAttributes through in Reflector, the managed part of the code (i.e. the point at which it transitions to the runtime and becomes an external call) is down in CustomAttribute.GetCustomAttributes.
At this point, the method is examining the bytes of the metadata surrounding the object for which the attributes are being loaded.
There is code in there which then does further reflection to find the runtime constructor being called. E.g.
[MyAttribute]
Would be calling the default, whereas
[MyAttribute(1, "hello", typeof(T))]
Would be calling a constructor that takes (Int, String, Type).
I can't see any evidence in there that any caching of instances is performed which therefore means that attribute instances are created on demand when they are reflected.
Proof
The aforementioned managed-runtime transition happends at CustomAttribute._CreateCaObject. Whilst not easy to statically analyse whether this method does in fact cache the instances it creates (it does potentially get enough state information in the form of a memory buffer pointer presumably indicating the location in metadata where the attribute declaration resides) we can look at the facts:
The constructor is always called, and
New constructor parameters are always read and fed in.
This tells me that the attribute is always constructed.
We can test for this, of course, by writing a piece of code in a test.
[TestMethod]
public void TestMethod1()
{
//if running in MSTest you have to allow for the test runner to reflect
//over the class as it looks for the TestClass attribute - therefore if our
//assumption is correct that a new instance is always constructed when
//reflecting, our counter check should start at 2, not 1.
Type t = typeof(AttributeTest);
var attributes =
t.GetCustomAttributes(typeof(AttributeTest.TheAttributeAttribute), false);
//check counter
Assert.AreEqual(2, AttributeTest.TheAttributeAttribute.Counter);
var attributes2 =
t.GetCustomAttributes(typeof(AttributeTest.TheAttributeAttribute), false);
//should be one louder (sorry, 'one bigger' - the Spinal Tap influence :) )
Assert.AreEqual(3, AttributeTest.TheAttributeAttribute.Counter);
}
[TheAttribute]
public class AttributeTest
{
public class TheAttributeAttribute : Attribute
{
static int _counter = 0;
public static int Counter { get { return _counter; } }
public TheAttributeAttribute()
{
_counter++;
Console.WriteLine("New");
}
}
}
Therefore an efficient use of metadata attributes would be to cache them in user code, unless of course the attribute is mutable in some way that makes it not applicable for all instances of a given T, or all 'instances' (in quotes because of course a method is only stored in memory once) of a method m for instances of type T).
Following this, therefore, an attribute is available to the GC once all references to it in code have been nulled. The same is true for all members of that attribute as well.
Therefore a method which uses GetCustomAttributes() to retrieve an attribute, uses it and then throws away the reference has just released a new instance of that attribute for the GC to clean up when it needs to.
Therefore - attribute instances are governed by the exact same memory management and lifetime rules as all class instances; therefore what #PieterG says in his answer is correct - the destructor could be called at any time after all references to that attribute have been released.
Whenever the GC Feels like it
Destructors cannot be called. They are invoked automatically.
Destructors (C# Programming Guide)
Related
I have a constructor for a class called ActNode which takes a class parameter called Act like this:
public Act Act; //the act affiliated with this node...
public ActNode(Act moAct, ...some others, not important) {
if (moAct == null)
throw new SomeException(); //this is never entered
Act = moAct;
... some other codes
}
The constructor above is the only constructor the ActNode has and anywhere in the code, the Act passed to the constructor is not null. Then, in one of the ActNode's methods, a bool flag of the Act is checked like this:
public void ActNodeMethod() {
if (Act.AnActFlagToBeChecked) { //FIXME this Act can be surprisingly null!
//do something
}
}
Thus, in a single thread environment, the Act.AnActFlagToBeChecked cannot throw NullException since the Act of an ActNode cannot be null. However, I use the ActNode in a multi-thread environment. It is not always, but sometimes the line above:
if (Act.AnActFlagToBeChecked) //FIXME this Act can be surprisingly null!
Can throw null exception.
Why is this so and how to fix it?
From reading a post in SO, it is said that this may happen if the Act is not initialized (therefore having default value of null) but the method is called. Yet in my implementation, there is no such case, because the Act everywhere in the code is never null when the constructor is called.
The only thing here is that I implement it in multi-thread environment where multiple ActNodes can call ActNodeMethod at the same time. But it shouldn't be a problem (or it could?) since each ActNode will have its own resource called Act associated to it (not a shared resource).
I am pretty confused here and would appreciate if someone can help enlightment me of the possible issues of the above implementation.
To give bigger context, ActNode is a TreeNode which I use to store a value representing the time needed to go to that node. I implement the ActNode in my searching tree algorithm to find the fastest solution to finish up a set of given "Acts". I use multi-threads because it can speed up the searching process.
This code has been UPDATED.
Robot.cs:
struct state systemcheck()
{
state stateInfo = new state();
public double x,y,z;
}
Main.cs:
public state stateInfo;
private readonly Sub cpnew;
public Main()
{
InitializeComponent();
cpnew = new Sub(this);
}
Sub.cs:
public state systinfo;
private readonly Main main;
public Sub(Main main)
{
InitializeComponent();
this.main = main;
systinfo = this.main.stateInfo;
}
Here,systinfo.X provides a null value. But mainfrm.stateInfo.X provides the correct value but throws marshal-by-reference class warning.
What is the correct way of initializing systinfo? The values of state are obtained from a robot connected from the external.
It's a good thing you asked - remember to always follow the warnings unless you absolutely know what you're doing. In this case, you most definitely do not know what you're doing.
Form is a class - and all classes are reference types in .NET. This has several implications, one of which is highly relevant here - they are always passed by reference. In other words, when you use Main main as an argument, you are already passing a reference (similar to passing a pointer to Main in C).
Using ref, you're passing a reference to the reference. This allows you to modify the outside reference from inside of the method. That's not what you want here - as a simple example, it would allow you to write an increment method:
public void Increment(ref int value)
{
value = value + 1;
}
If you didn't use ref, this would simply modify the local value of value. With ref, it modifies the local in the caller.
In your case, the proper code would be closer to
public state stateInfo;
private readonly Sub cpnew;
public Main()
{
InitializeComponent();
cpnew = new Sub(this);
}
Form2:
public state systinfo;
private readonly Main main;
public Sub(Main main)
{
InitializeComponent();
this.main = main;
systinfo = mainfrm.stateInfo;
}
So, what is the warning telling you? Form inherits from MarshalByRefObject. This implies that you might not actually be passing the real Form object - it's entirely possible you only have a proxy to a Form on a remote computer, for example. This means that all the calls on the type are automatically marshalled through the proxy, executed on the actual instance, and the result returned. Since state is a struct (and I'm betting it's because you don't understand the difference between C#'s struct and C's struct), it's a value-type - and if you are indeed holding a proxy instead of the real instance, this will cause a runtime exception.
To get around the warning, you could copy out the state to a local first - that makes it safe (and more importantly, obvious).
There's a lot of traps you can drop into when switching from C++ to C# - they look similar on the surface, but there's many differences. Try looking up a bit about whatever you're trying to use before you actually do - for example, looking up the ref keyword would make it obvious that you're making a pointer to a pointer, and looking up struct and class will tell you that they behave completely differently from C++. Just be careful.
Coding in C# idiomatically gets even more serious. For example, you usually create sub-forms and dialogs where you need them, rather than creating an instance in the constructor and reusing it when needed. And of course, circular references are usually a terrible idea - it's a great way to increase the code complexity, and it makes debugging and testing more expensive. Further refactoring hurts a lot more with circular references as well.
I have a class PluginProvider that is using a PluginLoader component to load plugins (managed/native) from the file system. Within the PluginProvider class, there is currently defined a property called 'PluginTypes' which calls the 'InitializePlugins' instance method on get().
class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
//isInitialized is set inside InitializePlugins method
if(!isInitialized)
{
InitializePlugins(); //contains thread safe code
}
//_pluginTypes is set within InitializePlugins method
return _pluginTypes;
}
}
}
I am looking at refactoring this piece of code. I want to know whether this kind of initialization is fine to do within a property. I know that heavy operations must not be done in a property. But when i checked this link : http://msdn.microsoft.com/en-us/library/vstudio/ms229054.aspx , found this " In particular, operations that access the network or the file system (other than once for initialization) should most likely be methods, not properties.". Now I am a bit confused. Please help.
If you want to delay the initialization as much as you can and you don't know when your property (or properties) will be called, what you're doing is fine.
If you want to delay and you have control over when your property will be called the first time, then you might want to make your method InitializePlugins() public and call it explicitly before accessing the property. This option also opens up the possibility of initializing asynchronously. For example, you could have an InitializePluginsAsync()that returns a Task.
If delaying the initialization is not a big concern, then just perform the initialization within the constructor.
This is of course a matter of taste. But what i would do depends on the length of the operation you're trying to perform. If it takes time to load the plugins, i would create a public method which any user would need to call before working with the class. A different approach would be to put the method inside the constructor, but IMO constructors should return as quickly as possible and should contain field / property initialization.
class PluginProvider
{
private bool _isInitialized;
IEnumerable<IPluginType> PluginTypes { get; set;}
public void Initialize()
{
if (_isInitialized)
{
return;
}
InitializePlugins();
_isInitialized = true;
}
}
Note the down side of this is that you will have to make sure the Initialize method was called before consuimg any operation.
Another thing that just came to mind backing this approach is exception handling. Im sure you wouldn't want your constructorcto be throwing any kind of IOException in case it couldn't load the types from the file system.
Any initialization type of code should be done in the constructor, that way you know it will be called once and only once.
public class PluginProvider
{
IEnumerable<IPluginType> PluginTypes
{
get
{
return _pluginTypes;
}
}
public PluginProvider()
{
InitializePlugins();
}
}
What you are doing there is called lazy initialization. You are postponing doing a potentially costly operation until the very moment its output is needed.
Now, this is not an absolute rule. If your InitializePlugins method takes a long time to complete and it might impact user experience, then you can consider moving it into a public method or even making it asynchronous and call it outside of the property: at app startup or whenever you find a good moment to call a long-lasting operation.
Otherwise, if it's a short lived one-time thing it can stay there. As I said, not an absolute rule. Generally these are some guidelines for whatever applies to a particular case.
Foreword: I am trying to describe the scenario very precisely here. The TL;DR version is 'how do I tell if a lambda will be compiled into an instance method or a closure'...
I am using MvvmLight in my WPF projects, and that library recently changed to using WeakReference instances in order to hold the actions that are passed into a RelayCommand. So, effectively, we have an object somewhere which is holding a WeakReference to an Action<T>.
Now, since upgrading to the latest version, some of our commands stopped working. And we had some code like this:
ctor(Guid token)
{
Command = new RelayCommand(x => Messenger.Default.Send(x, token));
}
This caused a closure (please correct me if I'm not using the correct term) class to be generated - like this:
[CompilerGenerated]
private sealed class <>c__DisplayClass4
{
public object token;
public void <.ctor>b__0(ReportType x)
{
Messenger.Default.Send<ReportTypeSelected>(new ReportTypeSelected(X), this.token);
}
}
This worked fine previously, as the action was stored within the RelayCommand instance, and was kept alive whether it was compiled to an instance method or a closure (i.e. using the '<>DisplayClass' syntax).
However, now, because it is held in a WeakReference, the code only works if the lambda specified is compiled into an instance method. This is because the closure class is instantiated, passed into the RelayCommand and virtually instantly garbage collected, meaning that when the command came to be used, there was no action to perform. So, the above code has to be modified. Changing it to the following causes that, for instance:
Guid _token;
ctor(Guid token)
{
_token = token;
Command = new RelayCommand(x => Messenger.Default.Send(x, _token));
}
This causes the compiled code to result in a member - like the following:
[CompilerGenerated]
private void <.ctor>b__0(ReportType x)
{
Messenger.Default.Send<ReportTypeSelected>(new ReportTypeSelected(X), this._token);
}
Now the above is all fine, and I understand why it didn't work previously, and how changing it caused it to work. However, what I am left with is something which means the code I write now has to be stylistically different based on a compiler decision which I am not privy to.
So, my question is - is this a documented behaviour in all circumstances - or could the behaviour change based on future implementations of the compiler? Should I just forget trying to use lambdas and always pass an instance method into the RelayCommand? Or should I have a convention whereby the action is always cached into an instance member:
Action<ReportTypeSelected> _commandAction;
ctor(Guid token)
{
_commandAction = x => Messenger.Default.Send(x, token);
Command = new RelayCommand(_commandAction);
}
Any background reading pointers are also gratefully accepted!
Whether you will end up with a new class or an instance method on the current class is an implementation detail you should not rely on.
From the C# specification, chapter 7.15.2 (emphasis mine):
It is explicitly unspecified whether there is any way to execute the block of an anonymous function other than through evaluation and invocation of the lambda-expression or anonymous-method-expression. In particular, the compiler may choose to implement an anonymous function by synthesizing one or more named methods or types.
-> Even the fact that it generates any methods at all is not specified.
Given the circumstances, I would go with named methods instead of anonymous ones. If that's not possible, because you need to access variables from the method that registers the command, you should go with the code you showed last.
In my opinion the decision to change RelayCommand to use WeakReference was a poor one. It created a lot more problems than it solved.
As soon as the lambda references any free variables (aka capture), then this will happen as it needs a common location (aka storage class/closure) to reference (and/or assign to) them.
An exercise for the reader is to determine why these storage classes cannot just be static.
I had trouble coming up with a good way to word this question, so let me try to explain by example:
Suppose I have some interface. For simplicity's sake, I'll say the interface is IRunnable, and it provides a single method, Run. (This is not real; it's only an example.)
Now, suppose I have some pre-existing class, let's call it Cheetah, that I can't change. It existed before IRunnable; I can't make it implement my interface. But I want to use it as if it implements IRunnable--presumably because it has a Run method, or something like it. In other words, I want to be able to have code that expects an IRunnable and will work with a Cheetah.
OK, so I could always write a CheetahWrapper sort of deal. But humor me and let me write something a little more flexible--how about a RunnableAdapter?
I envision the class definition as something like this:
public class RunnableAdapter : IRunnable {
public delegate void RunMethod();
private RunMethod Runner { get; set; }
public RunnableAdapter(RunMethod runner) {
this.Runner = runner;
}
public void Run() {
Runner.Invoke();
}
}
Straightforward enough, right? So with this, I should be able to make a call like this:
Cheetah c = new Cheetah();
RunnableAdapter ra = new RunnableAdapter(c.Run);
And now, voila: I have an object that implements IRunner and is, in its heart of hearts, a Cheetah.
My question is: if this Cheetah of mine falls out of scope at some point, and gets to the point where it would normally be garbage collected... will it? Or does this RunnableAdapter object's Runner property constitute a reference to the original Cheetah, so that it won't be collected? I certainly want that reference to stay valid, so basically I'm wondering if the above class definition is enough or if it would be necessary to maintain a reference to the underlying object (like via some private UnderlyingObject property), just to prevent garbage collection.
Yes, that reference remains valid, and can in fact be retrieved using the Delegate.Target property -- in your code, as ra.Runner.Target.
As others said it counts as a reference. You might find this story interesting.
http://asserttrue.blogspot.com/2008/11/garbage-collection-causes-car-crash.html
If not, that sounds like a broken garbage collector.
Yes, the delegate counts as a reference. Your object will not be garbage collected until the delegate is also unreachable.