C# Garbage Collector Ressurection NullRefException - c#

I have this code (taken for a very good and friendly web site)
public class B
{
static public A IntA;
}
public class A
{
private int x;
public A(int num)
{
x = num;
}
public void Print()
{
Console.WriteLine("Value : {0}", x);
}
~A()
{
B.IntA = this;
}
}
class RessurectionExample
{
// Ressurection
static void Main()
{
// Create A instance and print its value
A a = new A(50);
a.Print();
// Strand the A object (have nothing point to it)
a = null;
// Activate the garbage collector
GC.Collect();
// Print A's value again
B.IntA.Print();
}
}
It creates an instance of A with the value 50, prints it, strands the created object by setting his only reference to null, activates his Dtor and after being saved at B - prints it again.
Now, the weird thing is that when debugging, when the cursor points to the last line (B.IntA.Print()), the value of the static A member is null, after pressing F10, I get a NullReferenceException BUT the value of the static A member changes to what it should be.
Can anyone explain this phenomenon?

You need a call to GC.WaitForPendingFinalizers. Without this, your destructor won't actually get called in order.
static void Main()
{
// Create A instance and print its value
A a = new A(50);
a.Print();
// Strand the A object (have nothing point to it)
a = null;
// Activate the garbage collector
GC.Collect();
// Add this to wait for the destructor to finish
GC.WaitForPendingFinalizers();
// Print A's value again
B.IntA.Print();
}

Related

Prevent my windows application to run multiple times

I have an windows application built in visual studio that will deploy to other PC's with several users and i want to prevent my application to run multiple times is there any way to prevent it programmatically ? or in other way?
You can use a named mutex for that purpose. A named(!) mutex is a system-wide synchronization object. I use the following class (slightly simplified) in my projects. It creates an initially unowned mutex in the constructor and stores it in a member field during the object lifetime.
public class SingleInstance : IDisposable
{
private System.Threading.Mutex _mutex;
// Private default constructor to suppress uncontrolled instantiation.
private SingleInstance(){}
public SingleInstance(string mutexName)
{
if(string.IsNullOrWhiteSpace(mutexName))
throw new ArgumentNullException("mutexName");
_mutex = new Mutex(false, mutexName);
}
~SingleInstance()
{
Dispose(false);
}
public bool IsRunning
{
get
{
// requests ownership of the mutex and returns true if succeeded
return !_mutex.WaitOne(1, true);
}
}
public void Dispose()
{
GC.SuppressFinalize(this);
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
try
{
if(_mutex != null)
_mutex.Close();
}
catch(Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
_mutex = null;
}
}
}
This example shows, how to use it in a program.
static class Program
{
static SingleInstance _myInstance = null;
[STAThread]
static void Main()
{
// ...
try
{
// Create and keep instance reference until program exit
_myInstance = new SingleInstance("MyUniqueProgramName");
// By calling this property, this program instance requests ownership
// of the wrapped named mutex. The first program instance gets and keeps it
// until program exit. All other program instances cannot take mutex
// ownership and exit here.
if(_myInstance.IsRunning)
{
// You can show a message box, switch to the other program instance etc. here
// Exit the program, another program instance is already running
return;
}
// Run your app
}
finally
{
// Dispose the wrapper object and release mutex ownership, if owned
_myInstance.Dispose();
}
}
}
You can use this snippet to check whether instance is running or not and can alert user that another instance is running
static bool IsRunning()
{
return Process.GetProcesses().Count(p => p.ProcessName.Contains(Assembly.GetExecutingAssembly().FullName.Split(',')[0]) && !p.Modules[0].FileName.Contains("vshost")) > 1;
}

Memory will not release in C# singleton mode

I have a puzzle about singleton mode freeing object memory in C# between in C++;
Here C++ Code:
#include<iostream>
using namespace std;
class Rocket
{
private:
Rocket() { speed = 100; }
~Rocket() {}
static Rocket* ms_rocket;
public:
int speed;
static Rocket*ShareRocket()
{
if (ms_rocket == NULL)
ms_rocket = new Rocket();
return ms_rocket;
}
static void Close()
{
if (ms_rocket != NULL)
delete ms_rocket;
}
};
Rocket *Rocket::ms_rocket = NULL;
int main()
{
Rocket* p = Rocket::ShareRocket();
p->speed = 100;
cout << p->speed << endl;
Rocket::Close();
cout << p->speed << endl;
getchar();
}
When I use Rocket::Close(), the memory space which ms_rocket pointed to will be freed, ms_rocket become a wild pointer, and the second "cout<age<<endl" show is not 100, but when I use C# , I also use Dispose(), but still show 100. here the C# code:
class A : IDisposable
{
public int age;
public A() { }
public void Run()
{
Console.WriteLine("Run");
}
#region IDisposable Support
private bool disposedValue = false;
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
Console.WriteLine("A is release");
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(true);
}
#endregion
}
class B
{
static A a;
private B() { }
public static A Intance
{
get
{
if (a == null)
a = new A();
return a;
}
}
}
class Class1
{
public static void Main(string[] args)
{
A a = B.Intance;
a.age =100;
Console.WriteLine(a.age);
a.Dispose();
A a1 = B.Intance;
Console.WriteLine(a1.age);
Console.Read();
}
}
In C#, I think when I use Dispose(), the memory('a' object in B singleton) will be released, but in the second access, the age value should not be 100, and the static variable 'a' will become like a wild pointer.
Who can tell me why?
In C# Dispose mainly is used to release unmanaged resources as soon as they are not needed and not to free the memory occupied by object itself - it is handled by garbage collector which will free (when GC will decide that it needs to run) it only when it will become unaccessible from so called GC roots (and static variables are one of the GC roots, so B.Intance will hold the reference to this instance of A in the heap).
So first of all to free the memory taken by current instance of A you will need to set B.Instance to null (and wait for GC to run).
Also fundamentals of garbage collection in CLR can be useful.

Disposing static objects c#

I have a static class which implements Excel-related functions (Class Library).
This dll is added as a reference to other applications, where I'm trying to use those functions.
I know that static objects are disposed when the main program terminates. Can I somehow dispose it before?
In my code, If I call CreateExcelDocument(excelFile), and instance of Excel is running in the background (I can see it in windows' processes manager). But, when I call DisposeExcelDocument(); the instance remains. How can I dispose it?
My goal is to open multiple Excel files, one by one, create graphs from the file currently open, and then close and move on to the next one. Is it even possible?
Here is the code:
public static class ExcelUtils
{
#region Private Members
private static Application m_excelApp;
private static Workbook m_excelWorkBook;
private static Worksheet m_excelWorkSheet;
#endregion Private Members
#region Properties
public static Worksheet ExcelWorkSheet
{
get { return m_excelWorkSheet; }
set { m_excelWorkSheet = value; }
}
#endregion Properties
#region Public Functions
public static void CreateExcelDocument(string excelFile)
{
try
{
m_excelApp = new Application();
m_excelApp.DisplayAlerts = false;
m_excelWorkBook = m_excelApp.Workbooks.Add(Type.Missing);
m_excelWorkSheet = (Worksheet)m_excelApp.ActiveSheet;
m_excelApp.DefaultSheetDirection = (int)Constants.xlLTR;
m_excelWorkSheet.DisplayRightToLeft = false;
if (excelFile.CompareTo("") != 0)
{
m_excelWorkBook = m_excelApp.Workbooks.Open(excelFile);
m_excelWorkSheet = (Worksheet)m_excelApp.Worksheets.get_Item(1);
m_excelWorkSheet.Columns.ClearFormats();
m_excelWorkSheet.Rows.ClearFormats();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return;
}
}
public static void DisposeExcelDocument()
{
try
{
m_excelApp.Quit();
ReleaseObject(m_excelWorkSheet);
ReleaseObject(m_excelWorkBook);
ReleaseObject(m_excelApp);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return;
}
}
public static void ReleaseObject(object currentObject)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(currentObject);
currentObject = null;
}
catch (Exception ex)
{
currentObject = null;
Console.WriteLine(ex.ToString());
return;
}
finally
{
GC.Collect();
}
}
public static uint GetNumberOfRowsOrCols(string excelFile, bool getRows)
{
CreateExcelDocument(excelFile);
uint rowColNum = 0;
if (getRows)
rowColNum = (uint)m_excelWorkSheet.UsedRange.Rows.Count;
else
rowColNum = (uint)m_excelWorkSheet.UsedRange.Columns.Count;
DisposeExcelDocument();
return rowColNum;
}
#endregion Public Functions
}
First of all I agree with the comments regarding making this as non-static class.
But as far as your question is concerned, the Garbage Collector is not collecting the objects as you are not setting null to the class members, but just the local reference in ReleaseObject method.
To null the class members with least changes, will be to pass currentObject parameter to ReleaseObject method as ref, and have to use generics instead of object data type. So the method will become:
public static void ReleaseObject<T>(ref T currentObject) where T : class
and to call this method you will change like this:
ReleaseObject(ref m_excelWorkSheet);
You can leave the body of ReleaseObject method as it is, but I think calling GC.Collect() is not needed, and if you really have to, then call in from DisposeExcelDocument only once in the end, after you have called ReleaseObject for all the objects.

want to pass value using ref in c# but its not working like I think it should

Maybe what I want to do is just the wrong way of going about it. But i am trying to write a game debug printer thing. It is to write values to the screen in a sprite font for various things i tell the debugger to care about. My debugger class is simple , but it seems that in c# things are getting passed by value not reference. So I turn to the ref keyword, which seems to work okay if I pass in the right data type. The issue is that I have this method signature:
Dictionary<String, object> debugStrings = new Dictionary<String, object>();
...
...
public void addVariable(String index, ref object obj) //i think it needs to be a reference, not so sure though.
{
debugStrings.Add(index, obj);
}
This adds to the dictionary a variable to ultimately print to the screen along with a key for it to be known as.
The problem though arises when I try to use the above method:
debugPrinter.addVariable("myrotationvalue", ref this.Rotation);
as per the link in the comment I changed the code above to:
this.Rotation = 4;
object c = (object)this.Rotation;
this.Rotation = 20;
level.dbgd.addVariable("playerrot", ref c);
//always prints 4 out, i guess it still is not passing by reference?
So it doesn't give an error but always prints out 4. Not sure how I will ever get the reference to work.
Again on another edit took the references out:
this.Rotation = 20;
level.dbgd.addVariable("playerrot", this.Rotation);
this.Rotation = 4; //should draw to screen 4, doesn't draws 20
I apparently this is harder than I thought it would be a simple little fun class to work up before I hit the hay, ha ha ha... this is not boding well for the monday to come.
Full class:
namespace GameGridTest.GameGridClasses.helpers
{
public class DebugDrawer : DrawableGameComponent
{
Dictionary<String, object> debugStrings = new Dictionary<String, object>();
int currentX;
int currentY;
VictoryGame _game;
private SpriteBatch spriteBatch;
private SpriteFont spriteFont;
public DebugDrawer(VictoryGame game) : base(game)
{
_game = game;
currentX = _game.Window.ClientBounds.Width - 400; //draw the debug stuff on right side of screen
currentY = 5;
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
spriteFont = _game.Content.Load<SpriteFont>("fonts\\helpers\\fpsFont");
}
public void addVariable<T>(String index, AbstractDebugHandler<T> obj) //i think it needs to be a reference, not so sure though.
{
debugStrings.Add(index, obj);
}
public void removeVariable(String index)
{
debugStrings.Remove(index);
}
protected override void UnloadContent()
{
_game.Content.Unload();
}
public override void Update(GameTime gameTime)
{
}
public override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
foreach (object obj in debugStrings) //draw all the values
{
spriteBatch.DrawString(spriteFont, obj.ToString(), new Vector2(currentX, currentY), Color.White);
currentY += 30;
}
currentY = 5;
spriteBatch.End();
}
}
public abstract class AbstractDebugHandler<T>
{
public AbstractDebugHandler(T obj)
{
InnerObject = obj;
}
public T InnerObject { get; private set; }
public abstract string GetDebugString();
}
public class ThisDebugHandler: AbstractDebugHandler<object>{
public ThisDebugHandler(object innerObject) : base(innerObject){
}
public override GetDebugString(){
return InnerObject.Rotation; //??
}
}
}
You are confusing passing a reference and passing by reference.
It's true that parameters are passed by value, but that doesn't mean that you can't pass a reference type. The reference is passed by value, which means that the reference is copied to the stack, the object itself is not copied.
Passing by reference is used when you have to change the variable that you are passing in.
Just remove the ref keyword, and your code will work just fine.
Edit:
As you are passing a value type into the method, it will be boxed, so the value is actually copied. You will be displaying the copy of the value, not the live value. Passing the parameter by reference doesn't help either, as you have to copy the value to make an object reference to it.
If you want to display value types, you would rather send in a function that can retrieve the value instead of the value itself:
Dictionary<String, Func<object>> debugStrings = new Dictionary<String, Func<object>>();
public void addVariable(String index, Func<object> getValue) {
debugStrings.Add(index, getValue);
}
Usage:
debugPrinter.addVariable("myrotationvalue", () => this.Rotation);
Ref is giving the pointer of the variable to the other Method, this means that the other method can set the value of the variable and not only use the pointer to the object. This is verry serious! Take a look at following code:
public void Test(){
object a = new object();
Test(a);
if(a==null)
Debug.WriteLine("isNull");
else
Debug.WriteLine("isSet");
}
public void Test2(ref object obj){
obj = null;
}
You can have the same behavior without this passing the variable by ref. Box the valueTypes in a object so the pointer to the object can be stored and not the pointer to the variable.
For Example:
public abstract class AbstractDebugHandler<T>{
public AbstractDebugHandler(T obj){
InnerObject = obj;
}
public T InnerObject {get; private set;}
public abstract string GetDebugString();
}
public void addVariable<T>(String index, DebugHandler<T> obj)
{
debugStrings.Add(index, obj);
//to get debugString use
string debugValue = obj.GetDebugString();
// will always geht the current Value of the defined Object
}
In your case you would have to set "this" as the innerObject, because Rotation is a ValueType and you have to pass the Object containing the ValueType so both Methods "Debugger" and "callingMethod" are working on the Same Object "this". The DebugHandler Class can now handle the string conversion. See
public class ThisDebugHandler: AbstractDebugHandler<ThisType>{
public ThisDebugHandler(ThisType innerObject) : base(innerObject){
}
public override GetDebugString(){
return InnerObject.Rotation;
}
}
So if you would now call your debug method like:
public void MainMethod(){
this.Rotation = 4;
ThisDebugHandler handler = new ThisDebugHandler(this);
level.dbgd.addVariable<ThisType>("someIndex",handler );
this.Rotation = 20;
//level.dbgd.print();
// now prints 20
}
Would be glad helping you, so please ask if you have further questions

C# threading - Lock Object

I am trying to lock a "boxed" object in a c# app, is this not possible?
class t
{
System.Object t_x = new object();
public t(int p)
{
t_x = p;
}
public void w()
{
lock (t_x)
{
for (int i = 0; i < 4; i++)
{
{
t_x = ((int)t_x) + 1;
Console.WriteLine(t_x);
Thread.Sleep(1000);
}
}
}
}
}
In another class I can start 2 threads:
Thread b1 = new Thread(new ThreadStart(t1.w));
b1.Start();
Thread b2 = new Thread(new ThreadStart(t1.w));
b2.Start();
However the portion is not locked.
When I lock an arbitrary object (i.e. one created and not modified as object a=new object()) it locks well.
Is boxing operation somehow "depromotes" my Object??
No, you can't do this - the lock block is shorthand for the following:
try(Monitor.Enter(lockObject))
{
//critical section
}
finally
{
Monitor.Exit(lockObject)
}
The documentation for Monitor.Enter states, "Use Monitor to lock objects (that is, reference types), not value types. When you pass a value type variable to Enter, it is boxed as an object. If you pass the same variable to Enter again, it is boxed as a separate object, and the thread does not block"
You need to create a separate lock object. The problem is that you re-assign t_x inside the loop. Assuming thread b1 gets inside the loop before b2 gets to the lock statement, b2 will be allowed inside the lock statement because, by that time, t_x will be a new object that does not have a lock on it.
The lock (t_x) call boxes an integer as a temporary object. Each call to lock(t_x) creates a New object and locking is useless.
(Lock expects an object and creates a NEW temporary object from the integer)
Just create a seperate lock object like said above by Femaref.
You have to use an extra object for the lock
object lockObj = new object();
public void foo()
{
lock(lockObj)
{
//do stuff here
}
}
If you really want (need?) to lock on the object, you can use a kind of wrapper :
public class IntWrapper
{
public int Value{get;set;}
}
Or if you need to stay more abstract :
public class ObjectWrapper
{
public Object Value { get;set; }
}
If you want to recognise when the data is loaded and also if the use tries to use it before then, you can do something like this:
Have a boolean flag like you mention, but use a separate object to lock before accessing it to prevent cross-thread race conditions.
When the user tries to use the data, if it is not loaded (check the variable) you can add another event handler to the worker RunWorkerCompleted event, that will immediately do what the user wants when the data is loaded.
Example:
public class MyClass
{
private bool dataIsReady = false;
private object locker = new object();
BackgroundWorker worker;
public void Begin()
{
worker = new BackgroundWorker();
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
}
public void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lock (locker)
{
dataIsReady = true;
}
}
public void UseTriesToUseData()
{
lock (locker)
{
if (dataIsReady)
{
DoStuff();
}
else
{
this.worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(DoStuffCaller);
}
}
}
private void DoStuff()
{
// Do stuff with data.
}
private void DoStuffCaller(object sender, RunWorkerCompletedEventArgs e)
{
this.DoStuff();
}
}

Categories