Correct releasing zenon Objects in VSTA

Problem:
When a Macro with a zenon Object zenOn.IRecipes is set to null execute thrice the zenon RT can be crash.
Usually zenon Interface Objects (e.g. IVariables, IAlarms …) returns a pointer of the zenon-COM-Object but in the case of the IRecipes the zenon Interface returns a copy of the Object. If you set any zenon Interface Objects = null the pointer will released. In the case of the copy, the copy will exist until the Garbage Collector has time to release the Object. This depends on the CPU-Capacity and other .NET internal things. If the Macro is called again and the Garbage Collector doesn’t have the time to release the object, the Object will have a not valid condition and zenon RT will crash.

Example:

public void MacrocoloreSuVariabile()

{

zenOn.IRecipes projectRecipes;

zenOn.IRecipe ricetta;

zenOn.IRecipeValue item;

try

{

projectRecipes = this.Recipes();

if (projectRecipes != null)

{

ricetta = projectRecipes.Item("RICETTA_UNIFILARE");

if (ricetta != null)

{

for (int r = 0; r < ricetta.Count; r++)

{

item = ricetta.Item(r);

if (item != null)

{

item.Value = Convert.ToDouble(r);

item = null;

}

}

ricetta.ExecuteValues();

ricetta = null;

}

//This will cause the crash
projectRecipes = null;

}

}

catch (Exception ex)

{

Debug.Print("ERROR : " + ex.Message.ToString() + " " + ex.Source.ToString());

}

}

public void MacrocoloreSuVariabile()

{

zenOn.IRecipes projectRecipes;

zenOn.IRecipe ricetta;

zenOn.IRecipeValue item;

try

{

projectRecipes = this.Recipes();

if (projectRecipes != null)

{

ricetta = projectRecipes.Item("RICETTA_UNIFILARE");

if (ricetta != null)

{

for (int r = 0; r < ricetta.Count; r++)

{

item = ricetta.Item(r);

if (item != null)

{

item.Value = Convert.ToDouble(r);

item = null;

}

}

ricetta.ExecuteValues();

ricetta = null;

}

projectRecipes = null;

}

//Usually zenon Interface Objects (e.g. IVariables, IAlarms ...) returns a
//pointer of the zenon-COM-Object but in the case

//of the IRecipes the zenon Interface returns a copy of the Object.

//If you set any zenon Interface Objects = null the pointer will released.
//In the case of the copy, the copy will exist until

//the Garbage Collector have time to release the Object. This depends on
//the CPU-Capacity and other .NET internal things.

//In this case you must call the Garbage Collector manually to release the
//Object correctly.

GC.Collect();

GC.WaitForPendingFinalizers();

GC.Collect();

}

catch (Exception ex)

{

Debug.Print("ERROR : " + ex.Message.ToString() + " " + ex.Source.ToString());

}

}

 

Tags: