[Serializable]
public class GraphViewModel : ViewModelBase
{
public GraphViewModel()
{
//Constructor
}
public bool bool1 { get; set; }
public bool bool2 { get; set; }
public bool bool3 { get; set; }
public ObservableCollection<Foo> Foos { get; set; }
}
使用上面的示例类,我可以序列化并插入到二进制数据库字段中没问题。当我反序列化时,一切正常,但速度很慢(3到25秒之间)。注意:列表中只有5个项目。
我已将问题缩小到ObservableCollection。当我设置属性[XmlIgnore]时,反序列化的速度非常好,因为列表不包含在xml输出中。
我更愿意使用ObservableCollection并改进我的设置以更有效地处理这种情况,但无法在线找到解决方案。
修改 我尝试了以下属性:
[XmlArray(ElementName = "Foos")]
[XmlArrayItem(ElementName = "Foo")]
public ObservableCollection<Foo> Foos { get; set; }
它使Xml更具可读性,但不会提高反序列化速度。
答案 0 :(得分:2)
反序列化速度很可能是由于可观察集合引发的事件。
我在这种情况下所做的是将违规属性标记为XMLIgnore,然后添加一个可序列化的伪属性,但类型更简单,例如List&lt;&gt;。在新属性的getter和setter中,只需将数据移入和移出非序列化属性。
编辑:
我意识到最初的建议与当前的反序列化具有相同的性能损失,因此我修改了概念以允许向可观察集合添加一系列记录,同时抑制否则将引发的事件。
首先,我们需要创建一个继承自ObservableCollection的特殊类:
public class FooCollection : ObservableCollection<Foo>
{
}
在这个类中,我们需要添加一个允许我们添加一系列记录的方法,在本例中是List&lt;&gt;表格并表明我们在添加记录时不希望发生通知:
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&lt;&gt;属性:
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);
}
}
}