反序列化速度很可能是由于可观察集合引发的事件。
我在这些情况下所做的是将违规属性标记为XMLIgnore,然后添加一个可序列化的伪属性,但是是一个更简单类型的伪属性,例如列表<>。在新属性的getter和setter中,只需将数据移入和移出不可序列化的属性即可。
编辑:
我意识到,最初建议将具有相同的性能损失作为当前反序列化呢,所以我已经修改了这个概念,允许添加范围的记录,以观察集合,同时抑制了事件否则会被提出。
首先,我们需要创建一个从的ObservableCollection继承的特殊类:
public class FooCollection : ObservableCollection<Foo>
{
}
该类别中,我们需要添加一个方法,让我们添加了一系列的记录,在这种情况下列表<>形式,并指出,我们不希望发生,而我们所添加的记录通知:
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的系列化,并添加一个序列化的列表<>属性:
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);
}
}
}
我现在推行的概念。 – faldeland
@faldeland:我已经用更好的方法更新了答案,应该可以大大提高性能。 –
我期待明天实施这个... – faldeland