我遇到了一个我无法弄清楚如何解决的问题,所以我开始认为我不正确理解后台工作者。
我正在尝试使用后台工作人员来处理程序中的保存/加载功能,这意味着我希望工作人员调用我创建的序列化方法。
序列化方法采用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);