デシリアライズ速度は、監視可能なコレクションが発生するイベントが原因である可能性があります。
このような状況で私が行うことは、問題のあるプロパティをXMLIgnoreとしてマークしてから、シリアル化可能であるが、List<>などのより単純なタイプの疑似プロパティを追加することです。新しいプロパティのゲッターとセッターで、データをシリアル化できないプロパティに出し入れします。
編集:
最初の提案には現在の逆シリアル化と同じパフォーマンスペナルティがあることに気付いたので、概念を修正して、発生するイベントを抑制しながら、監視可能なコレクションに一連のレコードを追加できるようにしました。
まず、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);
}
}
}
}
}
最後に、FooCollectionのシリアル化を抑制し、シリアル化可能なList <>プロパティを追加するために、GraphViewModel内の実装を少し変更する必要があります。
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);
}
}
}