cross thread serialization

Mar 28, 2011 at 3:39 PM

I am storing objects in my database that have a solidcolorbrush as a property. I am using a custom serializer to serialize the solidcolorbrush because I want to be able to save my objects asynchronously, but in the Serialize method I get an UnauthorizedAccessException because of Invalid cross-thread access. Anyone know of a way around this problem? Here's what my serializer looks like:

public class BrushSerializer : BaseSerializer
    {

        public override bool CanSerialize(Type targetType)
        {
            return targetType.Equals(typeof(SolidColorBrush));
        }

        public override void Serialize(object target, BinaryWriter writer)
        {
            var data = (SolidColorBrush)target;
            writer.Write(data.Color.A);
            writer.Write(data.Color.R);
            writer.Write(data.Color.G);
            writer.Write(data.Color.B);
        }

        public override object Deserialize(Type type, BinaryReader reader)
        {
            return new SolidColorBrush(Color.FromArgb(
                reader.ReadByte(), reader.ReadByte(),
                reader.ReadByte(), reader.ReadByte()));
        }
    }
Thanks for your help.

Coordinator
Mar 28, 2011 at 3:55 PM

Do you absolutely have to serialize the SolidColorBrush? Typically I think it's a bad idea to serialize the view objects directly. I'm not sure if you are using MVVM or not, but in MVVM we'd only serialize attributes that are bound to the UI artifacts. For example, in the case of your SolidColorBrush, I wouldn't store a SolidColorBrush for state. Instead, why not store a byte[4] representing the channels, and then use a ValueConverter? Then you won't have the thread access issue. You can still use a SolidColorBrush in the UI, just create a value converter that on convert takes the byte array, makes a color and returns a solid color brush, and in the convert back takes the solid color brush and decomposes to the byte array. Then, you would serialize the bytes.

You could get the bytes in the serializer using a UI thread delegate but that would slow your process and could block the UI thread, especially if you are serializing lots of those objects.

I know I provided the serializer example but after thinking about it more I think the value converter is a much safer approach because the UI marshalling is done where it belongs (in the view) and then your serialization doesn't deal directly with view artifacts.

Coordinator
Apr 10, 2011 at 1:15 PM

The latest changeset should address your issue by making a copy to iterate instead of sharing the copy. Can you let me know if it resolves your problem? The auto-migration from the 1.0 format to 1.5 is coming later today.

Apr 10, 2011 at 5:14 PM

I am getting a targetInvocationException with an inner exception of Invalid cross-thread access. I am not currently using a custom serializer for the solidcolorbrush, however.

Coordinator
Apr 10, 2011 at 6:39 PM

I'm sorry, I cross-posted this. The issue you're having won't be fixed because you're using the control that is on the UI thread. I was actually intending to address a different issue ... sorry for the false alarm. You'll need to serialize the aRGB and use a converter or something else to get it onto the UI.