This question already has answers here:
When should I create a destructor?
(8 answers)
Closed 6 days ago.
I'm dealing with an C# windows form application and I need to run class destructor immediately right after destroying my object .
using System;
namespace Test
{
class TTTest
{
public TTTest()
{
Console.WriteLine("Constructor Called");
}
~TTTest()
{
Console.WriteLine("Destroyed called");
}
}
class Program
{
static void Main(string[] args)
{
TTTest obj1 = new TTTest();
TTTest obj2 = new TTTest();
obj1 = null;
obj2 = null;
Console.ReadKey();
}
}
}
If I run this code ... The result will be :
Constructor Called
Constructor Called
and wont be :
Constructor Called
Constructor Called
Destroyed called
Destroyed called
I want to force compiler to run Garbage collector and I can do that by :
GC.Collect
But I want to run Destructor of each class right after destroying each object without calling GC.Collect() in my routines automatically.
Is there any way ?
I need a good way to destroyed any things right after destroying my object , and do not repeat GC.Collect() again and again .
Thanks for any help.
In c# you would implement such a mechanic using Dispose().
class TTTest : IDisposable
{
public TTTest()
{
Console.WriteLine("Constructor Called");
}
public void Dispose()
{
Console.WriteLine("Dispose called");
}
}
class Program
{
static void Main(string[] args)
{
using (TTTest obj1 = new TTTest())
using (TTTest obj2 = new TTTest())
{
Console.ReadKey();
}
}
}
Related
This question already has answers here:
What happens if i return before the end of using statement? Will the dispose be called?
(5 answers)
Closed 4 years ago.
While working on my project, I was wondering, will using auto-destruct data if return will be inside of a using.
Example block of code:
using(ManagedObject obj = new ManagedObject())
{
int usualNumber = 0;
// some magic stuff
...
// magic stuff ends
return usualNumber; // return goes inside of 'using' brackets
}
And here is the question, will our ManagedObject which implements IDisposable be disposed by 'using' statement?
using statement can be seen as try and finally combination.
Your code is equivalent to:
ManagedObject obj = new ManagedObject();
try
{
int usualNumber = 0;
// some magic stuff
...
// magic stuff ends
return usualNumber;
}
finally
{
if (obj != null)
((IDisposable)obj ).Dispose();
}
I assume, that the answer to your question can be seen thanks to this code sample.
using is a Syntactic sugar, it need to contain an object which implements IDisposable interface when you leave the using scope .net will call the IDisposable.Dispose method Automatically.
Here is a sample c# online
when the program leave Test method. .net will call IDisposable.Dispose method Automatically
Yes, It will call the Dispose() function implemented by the IDisposable interface
class Program
{
static void Main(string[] args)
{
new Test().TestIt();
Console.Read();
}
}
class Test
{
public int TestIt()
{
using (ManagedObject obj = new ManagedObject())
{
int usualNumber = 0;
return usualNumber;
}
}
}
internal class ManagedObject : IDisposable
{
public void Dispose()
{
Console.WriteLine("Disposed");
}
}
Yes, even if you return from inside the using block, it will still call Dispose on obj.
Note that returning the usualNumber is perfectly fine, but if you were to return obj, that could be a problem because you would be returning a "disposed" object.
(Technically, objects could be usable after calling Dispose. For example, you could implement a Dispose that does nothing. But generally, most Dispose implementations would put the object in an unusable state).
im trying some different approach. Im not sure if its possible to place using() statement above methods or is there other way around.
public class Main
{
public Main()
{
using(Type t = new Type)
{
public void SomeFunction() {
t.toString()}
}
}
}
That is not possible, but you can do that like this:
using(Type t = new Type)
{
SomeFunction(t);
}
public void SomeFunction(Type tType)
{
tType.ToString();
}
Note : The t will be transferred to SomeFunction() and will be disposed at } of using block if the Class Type implements IDisposible, Since Using statement calls the Dispose method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon as Dispose is called
Here is a simple example:
class MyClass : IDisposable
{
bool working;
public MyClass()
{
working = true;
Thread t = new Thread(Worker);
t.Start();
}
void Worker()
{
while(working)
{}
}
public void Dispose()
{
working = false;
}
}
Is it okay to do this ? Will Dispose() even be called while the thread is still running? If not, how to better do it ?
Dispose will not be called unless you call it, either explicitly or through enclosing MyClass instantiation in using statement.
Will Dispose() even be called while the thread is still running?
It can be called like:
using (MyClass m = new MyClass())
{
System.Threading.Thread.Sleep(2000);
}
So once the using block ends, it will call the Dispose method in your class.
(Although your variable should be volatile to indicate that the field might be modified by multiple threads)
But the important thing to note is, that there is no magical thing about Dispose, even the using statement translates into try-finally , where Dispose is explicitly called in the finally block.
You shouldn't rely on that your Dispose method will be called.
You can wrap you class instance with WeakReference. The thread should stop its work once the reference is garbage collected.
class MyClass : IDisposable
{
class CancellationSignal
{
WeakReference _reference;
public bool IsWorking { get { return _working && _reference.IsAlive; } }
volatile bool _working;
public CancellationSignal(WeakReference reference)
{
if (reference == null) throw new ArgumentNullException("reference");
_reference = reference;
}
public void Signal()
{
_working = false;
}
}
CancellationSignal _cancellationSignal;
public MyClass()
{
_cancellationSignal = new CancellationSignal(new WeakReference(this));
Thread t = new Thread(Worker);
t.Start(_cancellationSignal);
}
static void Worker(object state)
{
var s = (CancellationSignal)state;
while (s.IsWorking)
{
//...
}
}
public void Dispose()
{
_cancellationSignal.Signal();
}
}
Personally I prefer to avoid using finalizers but I still have to say that another solution would be calling Signal in finalizer (and then you can remove WeakReference stuff):
~MyClass()
{
_cancellationSignal.Signal();
}
Notice that _working is declared as volatile. You can also use ManualResetEventSlim or even CancellationToken instead.
In both approaches (WeakReference and finalizer) you have to avoid passing this reference to Thread (because it would prevent your class instance from being garbage collected) therefore I added a CancellationSignal class and marked Worker as static.
I have a Class file to perform certain function , for example
public class clsFunction
{
public DataTable FunctionOne()
{
//some code
}
public void FunctionTwo()
{
//Some Code
}
}
SecondClass is use to call function from clsFunction , and this main class in running on a console program with multiple thread.
public class SecondClass
{
public void ThreadOne()
{
while(true){DataTable dt = new clsFunction().FunctionOne;}
}
public void ThreadTwo()
{
while(true){new clsFunction().FunctionTwo();}
}
}
class Main
{
static void Main (string[] args)
{
//Thread to start SecondClass.ThreadOne
//THread to start SecondClass.ThreadTwo
}
}
My concern is will my class value reinitialize to default value when I call new clsFunction() each time. for example , thread two may running it own value , when thread one is call , will all the thread two value change to it default value ?
Maybe you don't understand what new does. It creates an object. It's purpose is not to initialize something that already exists. Objects are independent.
Creating an object has no influence on any other object, except of course if the constructor does something to influence other objects.
Simple class using a TcpListener (this is just to present the problem, by no means this class makes any practical sence):
using System;
using System.Net.Sockets;
namespace NUnitTcp
{
public class Foo
{
TcpListener lst;
public Foo()
{
lst = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), 9090);
}
~Foo()
{
lst.Stop();
}
public void Start()
{
lst.Start();
}
public void Stop()
{
lst.Stop();
}
}
}
A simple application that uses Foo:
using System;
namespace NUnitTcp
{
class Program
{
static void Main(string[] args)
{
Foo f = new Foo();
f.Start();
}
}
}
This application runs fine, port is released as soon as the app ends and the app can be run again! Even without the destructor in Foo this would still happen!
A simple NUnit test with Foo:
using System;
using NUnitTcp;
using NUnit.Framework;
namespace NUnitTcpTests
{
[TestFixture]
public class TcpTests
{
[Test]
public void test1()
{
Foo f = new Foo();
f.Start();
Assert.True(true);
}
}
}
This test will run just once in the NUnit GUI thingy. Any subsequent execution of that test will throw an exception informing us that the port is in use. The NUnit GUI restart will release the port.
Would you consider this a bug? Seems to me like one...
CORRECTION - the test will randomly throw an exception, for me about 70% of the time.
The garbage collector is non-deterministic. It only closes promptly in the first example because the process exits. I strongly suggest you implement IDisposable instead of using a finalizer, then you can use:
using(Foo f = new Foo())
{
f.Start();
Assert.True(true);
}
safe in the knowledge that it will close promptly.
With something like:
public void Dispose()
{
if(lst != null) lst.Stop();
lst = null;
}
Port is in use until your Foo instance will not be collected by Garbage Collector. Also thus you have finalizer defined, it will require two garbage collection for finalizer to be called (Foo will be moved to finalization queue during first garbage collection, and finalizer will be possibly called during second garbage collection). If you want to be sure port will be released, I suggest you to close stop manually Foo in TearDown method:
private Foo _foo;
[SetUp]
public void Setup()
{
_foo = new Foo();;
}
[Test]
public void test1()
{
_foo.Start();
// Assert
}
[TearDown]
public void TearDown()
{
if (_foo != null)
_foo.Stop();
}
Also it would be nice to implement IDisposable on your Foo class, because it uses unmanaged resources, which should be released:
public class Foo : IDisposable
{
TcpListener lst;
public Foo()
{
lst = new TcpListener(System.Net.IPAddress.Parse("127.0.0.1"), 9090);
}
public void Dispose()
{
lst.Stop();
}
}