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: VSTA

