反序列化速度很可能是由于可观察集合引发的事件。
在这种情况下,我所做的是将有问题的属性标记为 XMLIgnore,然后添加一个可序列化但类型更简单的伪属性,例如 List<>。在新属性的 getter 和 setter 中,只需将数据移入和移出不可序列化的属性。
编辑:
我意识到最初的建议与当前的反序列化具有相同的性能损失,因此我修改了概念以允许将一系列记录添加到可观察集合中,同时抑制否则会引发的事件。
首先,我们需要创建一个继承自 ObservableCollection 的特殊类:
public class FooCollection : ObservableCollection<Foo>
{
}
在这个类中,我们需要添加一个允许我们添加一系列记录的方法,在本例中为 List<> 形式,并表明我们不希望在添加记录时发生通知:
private bool m_fSuppressNotifications;
public void AddRange(List<Foo> cItems)
{
if ((cItems == null) || (cItems.Count == 0)) {
this.Clear();
} else {
try
{
// Keep events from being fired
m_fSuppressNotifications = true;
foreach (var oFoo in cItems)
{
this.Add(oFoo);
}
}
finally
{
m_fSuppressNotifications = false;
// Raise the event to notify any listeners that the data has changed
this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
}
}
}
最后,我们需要覆盖 CollectionChanged 相关的元素并抑制或手动执行相关事件:
public override event NotifyCollectionChangedEventHandler CollectionChanged;
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
// Prevent infinite loop that could occur if handler changes the collection
using (BlockReentrancy())
{
if (!m_fSuppressNotifications)
{
// Get the current event
var oCollectionChangedEvent = this.CollectionChanged;
if (oCollectionChangedEvent != null)
{
foreach (EventHandler oHandler in oCollectionChangedEvent.GetInvocationList())
{
// Execute the handler
oHandler(this, e);
}
}
}
}
}
最后,我们需要稍微更改 GraphViewModel 内部的实现,以抑制 FooCollection 的序列化并添加一个可序列化的 List<> 属性:
public class GraphViewModel
{
[XmlIgnore]
public FooCollection Foos { get; set; }
[XmlArray(ElementName = "Foos")]
[XmlArrayItem(ElementName = "Foo")]
public List<Foo> FoosSerializable
{
get
{
return this.Foos.ToList<Foo>();
}
set
{
this.Foos.AddRange(value);
}
}
}