使用背景工作者调用序列化方法



我遇到了一个我无法弄清楚如何解决的问题,所以我开始认为我不正确理解后台工作者。

我正在尝试使用后台工作人员来处理程序中的保存/加载功能,这意味着我希望工作人员调用我创建的序列化方法。

序列化方法采用POCO并将其序列化。此POCO包含多个属性,其中之一是类型的刷子。

public Brush ShapeColor{ get; set; }

我想序列化颜色,但是由于我无法序列化刷子,所以我做了一个辅助属性:

public Color StoreColor
{
    get
    {          
         g = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).G;
         r = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).R;
         b = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).B;           
         return Color.FromRgb(r, g, b);
    }
    set {}
}

这在不使用BackgroundWorker的情况下工作正常。但是,一旦我尝试将方法调用doWork方法中的序列化方法,就会施放一个例外:

呼叫线程无法访问此对象,因为一个不同的线程拥有它。

这些:

g = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).G;
r = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).R;
b = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).B;   

我的理解是,通过使用BackgroundWorker来从另一个线程调用UI线程以外的其他线程调用序列化方法,我违反了规则,说明工作者无法访问UI元素。

老实说,我不太确定如何提出我的问题,但是我不可能从工人那里序列这些poco?与ShapeColor是刷子有关吗?

事先感谢我的不良解释:)

编辑:发布XML序列化方法。

public static void convertToXML<T>(T objectToSave, string path) where T : new()
    {
        StreamWriter streamWriter = null;
        try
        {               
            XmlSerializer serializer = new XmlSerializer(typeof(T));
            streamWriter = new StreamWriter(path, false);             
            XmlWriterSettings settings = new XmlWriterSettings()
            {
                Indent = true,
                OmitXmlDeclaration = true,
            };
            serializer.Serialize(streamWriter, objectToSave);
        }
        finally
        {
            // Close writer
            if (streamWriter != null)
            {
                streamWriter.Close();
            }
        }
    }

您已经遇到了Freezable对象。

这些对象通常只能从创建它们的线程中以Unfrozen状态处理(在您的情况下是Dispatcher线程)。

为了在另一个线程上处理(而不是操纵它们),您要么需要Freeze(),然后将它们交给其他线程,或使用Dispatcher.Invoke()上的Dispatcher线程进行调用。

int r =0;
int g =0;
int b =0;
//Marshalls back to UI thread
Dispatcher.Invoke(()=>{
 r = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).R;
 g = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).G;
 b = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).B;
});
//Creates object on BGW thread and can be safely used for serialization
return Color.FromRgb(r, g, b);

最新更新