NOTE: I'm interested in C#,Java and C++ most, but as this is the more academic question any language will do.
I know that this problem is solvable from outside, by using appropriate methods of given languages (calling free, Dispose, or by removing all references to instance).
My idea is that I create an instance, and in the constructor , I start the private timer. When the timer ends it will call some instance method and destroy the variable.
I think that in C# it should be possible to call Dispose on self, when the IDisposable is implemented, but this would not destroy the instace.
In C++ I could call the destructor, but that would lead to the memory leak, plus it is really bad practice.
In Java I have no clue, assigning to this it's not possible as it is final field.
So is there any way for instance, to destroy self?
Your question is very interesting, and I don't know of any other way to do so in C# but to force from the inside of the instance its destruction from the outside. So this is what I came up with to check if it is possible.
You can create the class Foo, which has event that is fired when the specific interval of the timer elapses. The class that is registered to that event (Bar) within event de-registers the event and sets the reference of the instance to null. This is how I would do it, tested and it works.
public class Foo
{
public delegate void SelfDestroyer(object sender, EventArgs ea);
public event SelfDestroyer DestroyMe;
Timer t;
public Foo()
{
t = new Timer();
t.Interval = 2000;
t.Tick += t_Tick;
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
OnDestroyMe();
}
public void OnDestroyMe()
{
SelfDestroyer temp = DestroyMe;
if (temp != null)
{
temp(this, new EventArgs());
}
}
}
public class Bar
{
Foo foo;
public Bar()
{
foo = new Foo();
foo.DestroyMe += foo_DestroyMe;
}
void foo_DestroyMe(object sender, EventArgs ea)
{
foo.DestroyMe -= foo_DestroyMe;
foo = null;
}
}
And in order to test this, you can set up a button click within a Form, something like this, and check it in the debugger:
Bar bar = null;
private void button2_Click(object sender, EventArgs e)
{
if(bar==null)
bar = new Bar();
}
So next time when you click the button, you will be able to see that Bar instance still exists but the Foo instance within it is null although it has been created within the Bar's constructor.
C++: If an object was allocated dynamically, it can delete its this pointer in its own function, provided the this pointer is never used again after that point.
No, there is no way to achieve what you are trying to do in C#.
If you consider an example :
public class Kamikadze {
......
private void TimerTick(..)
{
....
if(itsTime) {
DestroyMe();
}
}
.....
}
var kamikadze = new Kamikadze ();
after a while DestroyMe() will be called that cleans internal data.
But the reference kamikadze (pointer if you wish) is still valid and points to that memory location, so GC will not do anything, will not collect it, and instance of Kamikadze will remain in memory.
For C++ take a look at this:
http://www.parashift.com/c++-faq/delete-this.html
.
The closest thing in C# that I can think of:
On creation, every object stores a reference to itself in the GC root, e.g. by putting the reference into a class static list. Outside of the class, nobody is allowed to store (strong) references to the object. Everybody uses a WeakReference and checks if the Target is still IsAlive before touching the object. That way, the only thing that is keeping the object alive is the static reference.
When the object decides to kill itself, it simply removes the reference from the list. Sooner or later, the GC collects the object. Or, if you are really impatient, call GC.Collect() (ouch!).
But I really really would not recommend this solution!
It's much better put some flag into the class/object to signal whether it's still alive and make everybody check this flag before using the object. This can be combined with the IDisposable solution.
In C++, instances committing suicide are an integral part of the Finite State Machine Pattern:
//Context class contains a pointer to a State object.
void BattleshipGame::SetGameState(IState* state) {
game_state = state;
}
void BattleshipGame::Loss() {
game_state->Loss(this);
}
void BattleshipGame::Idle() {
game_state->Idle(this);
}
void BattleshipGame::FlyBy() {
game_state->FlyBy(this);
}
void BattleshipGame::Attack() {
game_state->Attack(this);
}
void BattleshipGame::Win() {
game_state->Win(this);
}
void BattleshipGame::Load() {
game_state->Loading(this);
}
//State base class contains methods for switching to every state.
class IState {
public:
virtual void Loading(BattleshipGame* context);
virtual void Idle(BattleshipGame* context);
virtual void FlyBy(BattleshipGame* context);
virtual void Attack(BattleshipGame* context);
virtual void Win(BattleshipGame* context);
virtual void Loss(BattleshipGame* context);
protected:
private:
};
//Implementations in the State base class are defined, but empty.
//Derived States only call what they need:
void StateIdle::Loss(BattleshipGame* context) {
//context->SetGameState(new StateLoss());
context->SetGameState(new StateLoss(context));
delete this;
}
void StateIdle::Idle(BattleshipGame* context) {
context->SetGameState(new StateIdle());
delete this;
}
void StateIdle::FlyBy(BattleshipGame* context) {
context->SetGameState(new StateFlyBy());
delete this;
}
void StateIdle::Win(BattleshipGame* context) {
context->SetGameState(new StateWin());
delete this;
}
//Similar design for all other states...
In C#, you're right you can implement IDisposable but the trick is instead of calling Dispose method make use of the using statement.
class Program
{
static void Main(string[] args)
{
using (MyClass obj = new MyClass())
{
obj.SayHello();
}
// obj.SayHello(); // Error: The name 'obj' does not exist in the current context
}
}
class MyClass : IDisposable
{
public void SayHello()
{
Console.WriteLine("Hello");
}
public void Dispose()
{
// Do something (e.g: close some open connection, etc)
}
}
For Reference: microsoft-docs/using-statement
I recommend using NFTLKEY. You can easily get it from the Nuget package. Best of all, it's open source: github project
Easier to understand than the examples here
Related
So, I have this class for dealing with timers in MVVM:
class RecognitionProcessTimer
{
DispatcherTimer analysisProcessTimer;
public int Duration { get; set; }
public RecognitionProcessTimer()
{
this.Duration = 500;
}
public void StartTimer()
{
analysisProcessTimer = new DispatcherTimer();
analysisProcessTimer.Interval = TimeSpan.FromMilliseconds(this.Duration);
analysisProcessTimer.Tick += AnalysisProcessTimer_Tick;
analysisProcessTimer.Start();
}
public void StopTimer()
{
if (analysisProcessTimer != null)
{
analysisProcessTimer.Stop();
analysisProcessTimer = null;
}
}
private void AnalysisProcessTimer_Tick(object sender, object e)
{
analysisProcessTimer.Stop();
// C# code current object variables from the other class
}
}
So, I have an analysis class that will do analysis on every tick of the timer. The RecognitionProcessTimer will be initialized and Start() on this analysis class's code but the timer's AnalysisProcessTimer_Tick event needs to check and call some current analysis class object variables. How do I go on achieving this?
I've tried to initialize the analysis class on tick method but then I lose all the data on there as a new object is used instead of the using the object that initialize the RecognitionProcessTimer class.
TLDR: I'm trying to use the variables from the class that initialized RecognitionProcessTimer from RecognitionProcessTimer's tick method.
If the question seems unclear, then please let me know and I'll clarify further.
P.S: Can't use static variables.
I'm completely confused about how event handler can affect in garbage collection operation.
For example, why object a1 not collected by garbage collection ( the destructor of a1 is not calling):
Even after unsubscribing timeChange eventHandler the destructor isn't called by garbage collector.
Best regards.
public class B
{
private void button1_Click(object sender, EventArgs e)
{
A a1 = new A();
a1.timeChange += A1_timeChange;
a1.Start();
a1 = null;
GC.Collect();
}
private void A1_timeChange(object sender, EventArgs e)
{
MessageBox.Show(((DateTime)sender).ToString() );
}
}
public class A
{
~A()
{
MessageBox.Show("A Collected");
}
public void Start()
{
if (timeChange != null)
{
Task.Factory.StartNew(() => {
while (true)
{
timeChange(DateTime.Now, null);
System.Threading.Thread.Sleep(3000);
}
});
}
}
public event EventHandler timeChange;
}
In summary
It is not the event itself that is causing this, but rather referencing an instance member of class A from a long running thread using a closure.
The event itself is not the issue, or is it?
This code a1.timeChange += A1_timeChange; causes a delegate inside class A that implements the event public event EventHandler timeChange to reference A1_timeChange inside class B.
So, the reference is the other way around
In your scenario, if you got rid of all references to class B, but did not unsubscribe from the event, then the event handler in A that points to a handler method in B could keep class B reachable, and therefore not GC'ed
What is really happening
Your class A is accessible from one of the GC roots (specifically, actively running threads), it's still reachable and therefore, not collected - read more
You have spawned an eternally running task (well it will stop when the app closes / foreground thread terminates) with this code
Task.Factory.StartNew(() => {
while (true)
{
timeChange(DateTime.Now, null);
System.Threading.Thread.Sleep(3000);
}
The thing is, that you're using a lambda that closes over the timeChange event, and that makes a compiler to generate a class that simply references class A
One more thing, just by having a descructor (which is compiled to a finalizer) you prolong the lifetime of your object by one GC collection - on the first GC, your object will be marked as unreachable, and will be put onto finalization queue. And on the next GC, the finalizer will actually run - read more
I am brand new to C# (I apologise if my question is noobish - I'm teaching myself, so it's a bumpy process). I am trying to develop a winform and since some of the methods are pretty long, I am trying to keep it in a couple classes. This is what I'm kind of hoping to achieve:
public partial class formMainForm : Form
{
public formMainForm()
{
InitializeComponent();
}
private void UpDown1_ValueChanged(object sender, EventArgs e)
{
longCalculations.LongMethod1();
}
}
public class longCalculations
{
private void LongMethod1()
{
// Arbitrarily long code goes here
}
}
I'm doing this in an attempt to keep the formMainForm class tidy and be able to split any calculations into manageable chunks. However, I'm encountering problems with using form controls (e.g. check boxes, numeric up-down controls, etc.) in my non-form classes.
If I leave them as is (e.g. CheckBox1) I get a the name does not exist in the current context error. I searched around and I found that it's because that box is defined in a different class. However, if I change it to formMainForm.CheckBox1, the error is now an object reference is required for the non-static field, method or property. Again, I looked around and it appears that that is due to the form initialization method not being static.
If I change public formMainForm() to static formMainForm(), the error now moves to InitializeComponent(); and I do not know where to go from here. I also tried making an instantiation of the formMainForm() method, but that didn't do anything (the code I attempted to use is below. I found it somewhere on this site as an answer to a similar problem).
private void formLoader(object sender, EventArgs e)
{
shadowrunMainForm runForm = new shadowrunMainForm();
runForm.Show();
}
How can I use the formcontrol names in other classes?
P.S. It is my first post here - I am super sorry if I have missed this question already being asked somewhere. I did search, but I didn't find what I was looking for.
EDIT
It seems I hadn't made myself clear - this was just an example of code and my problem is with the second class, not the first one. I have now simplified the code to:
public partial class formMainForm : Form
{
public formMainForm()
{
InitializeComponent();
}
}
public class longCalculations
{
private void LongMethod1()
{
List<CheckBox> listOfBoxes = new List<CheckBox>();
listOfBoxes.Add(CheckBox1);
// The code displays an "object reference is required for the non-static field, method or property" error at this stage. Changing the "CheckBox1" to formMainForm.CheckBox1 doesn't help
// Arbitrarily long code goes here
}
}
LongMethod1 works perfectly fine when placed in the formMainForm partial class. Moving it to the other form makes it unable to take data from those checkboxes.
I believe this line longCalculations.LongMethod1(); is throwing error cause you are trying to access a instance method as if it's a static method and as well it's defined as private method which won't be accessible outside the class. You need to create an instance of longCalculations class before accessing any of it's member or method(s) and mark the method public like
private void UpDown1_ValueChanged(object sender, EventArgs e)
{
longCalculations ln = new longCalculations();
ln.LongMethod1();
}
public class longCalculations
{
public void LongMethod1()
{
// Arbitrarily long code goes here
}
}
(OR) If you really want it to be a static method then define accordingly with static modifier like
public class longCalculations
{
public static void LongMethod1()
{
// Arbitrarily long code goes here
}
}
Now you can call it like the way you are trying
public static class longCalculations
{
public static void LongMethod1()
{
// Arbitrarily long code goes here
}
}
If you're going to make a call longCalculations.LongMethod1();, then you need to make your class static as such.
Or you leave it as not static method by calling
longCalculations lc = new longCalculations()
lc.LongMethod1();
As for accessing controls in separate classes, you can pass in the form and make the controls public which can be dangerous.
So on your Form.designer.cs, change any control you may have to public modifier. Then you would make a call like this...
private void UpDown1_ValueChanged(object sender, EventArgs e)
{
longCalculations.LongMethod1(this);
}
public void LongMethod1(Form1 form)
{
// Arbitrarily long code goes here
form.label1.Text = someString;
//more settings and whatnot
}
Or do something like this:
public class longCalculations
{
public string LongMethod1()
{
// Arbitrarily long code goes here
return myString;
}
}
longCalculations lc = new longCalculations()
string result = lc.LongMethod1();
this.label1.Text = result;
Ideally, your longCalculations class would not attempt to modify the form directly. Instead it would return an object that the form could use to update its controls.
If you need to access the form directly from the longCalculations class, first change the method to accept an instance of your form
public void LongMethod1(formMainForm myForm)
Then you can pass the form itself as a parameter
var calc = new longCalculations();
calc.LongMethod1(this);
In your other class, you need to have an instance of your formMainForm class:
var myForm = new formMainForm();
Then you can access its members like this:
myForm.CheckBox1.Checked = true;
I was working on creating a custom control with Command behavior and came across something odd. Some articles I found declared the CanExecuteChangedHandler EventHandler as static and others were non-static. Microsoft's SDK documentation shows static but when I declare it as static I get odd behavior when using multiple controls.
private static EventHandler canExecuteChangedHandler;
private void AddSecureCommand(ISecureCommand secureCommand)
{
canExecuteChangedHandler = new EventHandler(CanExecuteChanged);
securityTypeChangedHandler = new EventHandler(SecurityTypeChanged);
if (secureCommand != null)
{
secureCommand.CanExecuteChanged += canExecuteChangedHandler;
secureCommand.SecurityTypeChanged += securityTypeChangedHandler;
}
}
Does anyone know the proper way? Am I doing something wrong that is causing the static EventHandler not to work?
The stated reason for keeping a local copy of EventHandler is that the WPF commanding sub-system uses weak references internally and therefore we need to keep a reference to the specific delegate object that is added to the CanExecuteChanged event. If fact, anytime we are adding to any commanding sub-system event, we should also observe this practice, as you have for SecurityTypeChanged.
The short answer to your question is that canExecuteChangedHandler can be static, but you must be careful to only initialize it once. The reason it can be static is that all new EventHandler(CanExecuteChanged) will do the same thing if CanExecuteChanged is static. The reason to initialize it once is that different instances are different.
A private property that has the right read-only semantics is:
static EventHandler canExecuteChangedHandler
{
get
{
if (internalCanExecuteChangedHandler == null)
internalCanExecuteChangedHandler = new EventHandler(CanExecuteChanged);
return internalCanExecuteChangedHandler;
}
}
static EventHandler internalCanExecuteChangedHandler;
but this only works if CanExecuteChanged is static. If it is not, then remove the static qualifiers. In either case you have to be careful to actually use the property.
In this particular example, the second time that AddSecureCommand is called the first canExecuteChangedHandler is at risk of being garbage collected.
Finally, if this all sounds like black-magic, here is a code example to show what is happening.
public class Container
{
private WeakReference reference;
public object Object
{
get { return reference.IsAlive ? reference.Target : null; }
set { reference = new WeakReference(value); }
}
}
public class DelegateTest
{
private EventHandler eventHandler;
private Container container1;
private Container container2;
void MyEventHandler(object sender, EventArgs args)
{
}
public DelegateTest()
{
this.eventHandler = new EventHandler(MyEventHandler);
this.container1 = new Container { Object = this.eventHandler };
this.container2 = new Container { Object = new EventHandler(MyEventHandler) };
GC.Collect();
Console.WriteLine("container1: {0}", this.container1.Object == null);
Console.WriteLine("container2: {0}", this.container2.Object == null);
}
}
This produces this output:
container1: False
container2: True
which indicates that during the garbage collection that the second container had its EventHandler garbage-collected "out from underneath it". This is by design the way that weak references work and the explanation for you need to keep a reference to it yourself.
I have a class that is a "manager" sort of class. One of it's functions is to signal that the long running process of the class should shut down. It does this by setting a boolean called "IsStopping" in class.
public class Foo
{
bool isStoping
void DoWork() {
while (!isStopping)
{
// do work...
}
}
}
Now, DoWork() was a gigantic function, and I decided to refactor it out and as part of the process broke some of it into other classes. The problem is, Some of these classes also have long running functions that need to check if isStopping is true.
public class Foo
{
bool isStoping
void DoWork() {
while (!isStopping)
{
MoreWork mw = new MoreWork()
mw.DoMoreWork() // possibly long running
// do work...
}
}
}
What are my options here?
I have considered passing isStopping by reference, which I don't really like because it requires there to be an outside object. I would prefer to make the additional classes as stand alone and dependancy free as possible.
I have also considered making isStopping a property, and then then having it call an event that the inner classes could be subscribed to, but this seems overly complex.
Another option was to create a "Process Cancelation Token" class, similar to what .net 4 Tasks use, then that token be passed to those classes.
How have you handled this situation?
EDIT:
Also consider that MoreWork might have a EvenMoreWork object that it instantiates and calls a potentially long running method on... and so on. I guess what i'm looking for is a way to be able to signal an arbitrary number of objects down a call tree to tell them to stop what they're doing and clean up and return.
EDIT2:
Thanks for the responses so far. Seems like there's no real consensus on methods to use, and everyone has a different opinion. Seems like this should be a design pattern...
You can go two ways here:
1) The solution you've already outlined: pass a signaling mechanism to your subordinate objects: a bool (by ref), the parent object itself cloaked in an interface (Foo: IController in the example below), or something else. The child objects check the signal as needed.
// Either in the MoreWork constructor
public MoreWork(IController controller) {
this.controller = controller;
}
// Or in DoMoreWork, depending on your preferences
public void DoMoreWork(IController controller) {
do {
// More work here
} while (!controller.IsStopping);
}
2) Turn it around and use the observer pattern - which will let you decouple your subordinate objects from the parent. If I were doing it by hand (instead of using events), I'd modify my subordinate classes to implement an IStoppable interface, and make my manager class tell them when to stop:
public interface IStoppable {
void Stop();
}
public class MoreWork: IStoppable {
bool isStopping = false;
public void Stop() { isStopping = true; }
public void DoMoreWork() {
do {
// More work here
} while (!isStopping);
}
}
Foo maintains a list of its stoppables and in its own stop method, stops them all:
public void Stop() {
this.isStopping = true;
foreach(IStoppable stoppable in stoppables) {
stoppable.Stop();
}
}
I think firing an event that your subclasses subscribe to makes sense.
You could create a Cancel() method on your manager class, and on each of your other worker classes. Base it on an interface.
The manager class, or classes that instantiate other worker classes, would have to propagate the Cancel() call to the objects they are composed of.
The deepest nested classes would then just set an internal _isStopping bool to false and your long-running tasks would check for that.
Alternatively, you could maybe create a context of some sort that all the classes know about and where they can check for a canceled flag.
Another option was to create a
"Process Cancelation Token" class,
similar to what .net 4 Tasks use, then
that token be passed to those classes.
I am not familiar with this, but if it is basically an object with a bool property flag, and that you pass into each class, then this seems like the cleanest way to me. Then you could make an abstract base class that has a constructor that takes this in and sets it to a private member variable. Then your process loops can just check that for cancellation.
Obviously you will have to keep a reference to this object you have passed into your workers so that it's bool flag can be set on it from your UI.
Your nested types could accept a delegate (or expose an event) to check for a cancel condition. Your manager then supplies a delegate to the nested types that checks its own "shouldStop" boolean. This way, the only dependency is of the ManagerType on the NestedType, which you already had anyway.
class NestedType
{
// note: the argument of Predicate<T> is not used,
// you could create a new delegate type that accepts no arguments
// and returns T
public Predicate<bool> ShouldStop = delegate() { return false; };
public void DoWork()
{
while (!this.ShouldStop(false))
{
// do work here
}
}
}
class ManagerType
{
private bool shouldStop = false;
private bool checkShouldStop(bool ignored)
{
return shouldStop;
}
public void ManageStuff()
{
NestedType nestedType = new NestedType();
nestedType.ShouldStop = checkShouldStop;
nestedType.DoWork();
}
}
You could abstract this behavior into an interface if you really wanted to.
interface IStoppable
{
Predicate<bool> ShouldStop;
}
Also, rather than just check a boolean, you could have the "stop" mechanism be throwing an exception. In the manager's checkShouldStop method, it could simply throw an OperationCanceledException:
class NestedType
{
public MethodInvoker Stop = delegate() { };
public void DoWork()
{
while (true)
{
Stop();
// do work here
}
}
}
class ManagerType
{
private bool shouldStop = false;
private void checkShouldStop()
{
if (this.shouldStop) { throw new OperationCanceledException(); }
}
public void ManageStuff()
{
NestedType nestedType = new NestedType();
nestedType.Stop = checkShouldStop;
nestedType.DoWork();
}
}
I've used this technique before and find it very effective.
Litter your code with statements like this wherever it is most sensible to check the stop flag:
if(isStopping) { throw new OperationCanceledException(); }
Catch OperationCanceledException right at the top level.
There is no real performance penalty for this because (a) it won't happen very often, and (b) when it does happen, it only happens once.
This method also works well in conjunction with a WinForms BackgroundWorker component. The worker will automatically catch a thrown exception in the worker thread and marshal it back to the UI thread. You just have to check the type of the e.Error property, e.g.:
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if(e.Error == null) {
// Finished
} else if(e.Error is OperationCanceledException) {
// Cancelled
} else {
// Genuine error - maybe display some UI?
}
}
You can flatten your call stack by turning each DoWork() call into a command using the Command pattern. At the top level, you maintain a queue of commands to perform (or a stack, depending on how your commands interact with each other). "Calling" a function is translated to enqueuing a new command onto the queue. Then, between processing each command, you can check whether or not to cancel. Like:
void DoWork() {
var commands = new Queue<ICommand>();
commands.Enqueue(new MoreWorkCommand());
while (!isStopping && !commands.IsEmpty)
{
commands.Deque().Perform(commands);
}
}
public class MoreWorkCommand : ICommand {
public void Perform(Queue<ICommand> commands) {
commands.Enqueue(new DoMoreWorkCommand());
}
}
Basically, by turning the low-level callstack into a data structure you control, you have the ability to check stuff between each "call", pause, resume, cancel, etc..