gamesmeister
asked on
Serialization and Event Publishers
Hi
I have an application consisting of Form A and Class B. Class B stores a set of values that I want to save to file, and is therefore Serializable. However, I also added an event to it so that when one of the values changed, a subscriber (in this case Form A) was notified, and could refresh itself.
What actually happened was that when I attempted to write Class B to a filestream, it failed with a 'NonSerializable object' error - the object in question was the form.
Is this because I've added the form to Class B as a subscriber, and therefore .NET assumes it must also serialize the form? Assuming it is, what is the 'best practice' for dealing with this situation, bearing in mind that I can't mark an event as NonSerializable? Encapsulate Class B within another class that publishes the event? (I was hoping to avoid this, as it takes the responsibility of its own objects away from Class B, and means every change to variables within Class B will have to go through this wrapper).
Many thanks
Gerry
I have an application consisting of Form A and Class B. Class B stores a set of values that I want to save to file, and is therefore Serializable. However, I also added an event to it so that when one of the values changed, a subscriber (in this case Form A) was notified, and could refresh itself.
What actually happened was that when I attempted to write Class B to a filestream, it failed with a 'NonSerializable object' error - the object in question was the form.
Is this because I've added the form to Class B as a subscriber, and therefore .NET assumes it must also serialize the form? Assuming it is, what is the 'best practice' for dealing with this situation, bearing in mind that I can't mark an event as NonSerializable? Encapsulate Class B within another class that publishes the event? (I was hoping to avoid this, as it takes the responsibility of its own objects away from Class B, and means every change to variables within Class B will have to go through this wrapper).
Many thanks
Gerry
Please show your code.
ASKER
Code as follows (names changed to protect the innocent). When I try to serialize an instance of MyClass, I get the following error
************************** ********** ********** ********** ********** **
An unhandled exception of type 'System.Runtime.Serializat ion.Serial izationExc eption' occurred in mscorlib.dll
Additional information: The type MyForm in Assembly MyExe, Version=1.0.1886.24124, Culture=neutral, PublicKeyToken=null is not marked as serializable.
************************** ********** ********** ********** ********** ****
public class MyForm
{
public MyForm()
{
MyClass mc = new MyClass();
mc.ArrayListChanged +=new EventHandler(mc_ArrayListC hanged);
}
private void mc_ArrayListChanged(object sender, EventArgs e)
{
//update list view on Form
}
}
[Serializable]
public class MyProject
{
private ArrayList myArray;
protected event EventHandler arrayListChanged;
public MyProject()
{
myArray = new ArrayList();
}
public event EventHandler ArrayListChanged
{
add {arrayListChanged += value;}
remove {arrayListChanged -= value;}
}
public void AddString(string myString)
{
myArray.Add(myString);
if (arrayListChanged != null)
{
OnArrayListChanged(new EventArgs());
}
}
protected void OnArrayListChanged(System. EventArgs e)
{
arrayListChanged (this, e);
}
}
**************************
An unhandled exception of type 'System.Runtime.Serializat
Additional information: The type MyForm in Assembly MyExe, Version=1.0.1886.24124, Culture=neutral, PublicKeyToken=null is not marked as serializable.
**************************
public class MyForm
{
public MyForm()
{
MyClass mc = new MyClass();
mc.ArrayListChanged +=new EventHandler(mc_ArrayListC
}
private void mc_ArrayListChanged(object
{
//update list view on Form
}
}
[Serializable]
public class MyProject
{
private ArrayList myArray;
protected event EventHandler arrayListChanged;
public MyProject()
{
myArray = new ArrayList();
}
public event EventHandler ArrayListChanged
{
add {arrayListChanged += value;}
remove {arrayListChanged -= value;}
}
public void AddString(string myString)
{
myArray.Add(myString);
if (arrayListChanged != null)
{
OnArrayListChanged(new EventArgs());
}
}
protected void OnArrayListChanged(System.
{
arrayListChanged (this, e);
}
}
ASKER
Sorry, the class should be called MyClass, not MyProject
Where is serialization code? It looks like you are trying to serialize MyForm and not MyClass.
ASKER
The Serialization code is in a class library, called from MyForm. It receives an object and a path, and saves it as per the following. The object I'm passing as 'data' is the instance of MyClass (mc). One other thing - this all worked fine until I added the event handler to MyClass
public class BinaryPersistence : IPersistence
{
private object storedData;
private Stream stream;
public BinaryPersistence()
{
}
public void StoreFile(object data, string path)
{
if (data.Equals(null))
{
throw (new ArgumentNullException("dat a", "No data passed to store"));
}
else
{
if (path.Equals(null))
{
throw (new ArgumentNullException("pat h", "Filename cannot be null"));
}
}
stream = new FileStream(path,FileMode.C reate,File Access.Wri te);
StoreStream(data);
}
private void StoreStream(object data)
{
IFormatter f = new BinaryFormatter();
f.Serialize(stream, data);
stream.Close();
}
}
public class BinaryPersistence : IPersistence
{
private object storedData;
private Stream stream;
public BinaryPersistence()
{
}
public void StoreFile(object data, string path)
{
if (data.Equals(null))
{
throw (new ArgumentNullException("dat
}
else
{
if (path.Equals(null))
{
throw (new ArgumentNullException("pat
}
}
stream = new FileStream(path,FileMode.C
StoreStream(data);
}
private void StoreStream(object data)
{
IFormatter f = new BinaryFormatter();
f.Serialize(stream, data);
stream.Close();
}
}
ASKER
From the lack of response, can I assume that it's normally perfectly ok to add Event Handlers to a serializable class, and that there's something else wrong here?
Currently I have no answer, I will try to make small test later.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
That's an excellent workaround, thanks Alex