2012-02-21 8 views
0

私は、集中的なプロセスの結果を表す複雑なデータ構造を返すWebサービスを持っています。サービスを応答可能にするために、プロセスは非同期タスクで実行されます。長時間実行されたタスクの結果と以前の結果の比較

サービスが初めて呼び出されると、空のデータ構造が返され、タスクが開始されました。後続のサービスコールは、タスクが完了するまで、キャッシュされたデータを返します。終了したら、結果が実際に変更されたかどうかを判断する必要があります。その場合、結果が更新された日時を示すプロパティを更新し、サービスによって新しい構造体が返されるようにキャッシュされたデータをリセットします。将来的には、さまざまな理由に基づいて、タスクが再開され、ロジックが繰り返されます。

私は、結果が「キャッシュされた」データから変更されたかどうかを判断する最も効率的な方法を探しています。最も単純なのは、構造内のすべてのオブジェクトにEqualsを実装することです。これは、子の等価性に基づいて親の等価性を持つことです。ルートオブジェクトでEqualsを呼び出すと、望ましい結果が得られます。しかし、構造全体をクロールする必要があります。これが最良のアプローチです。

また、元のコピーから開始し、構造内のオブジェクトが変更されたことを示すために 'IsDirty'フラグを使用することを考えましたが、コピー操作がパフォーマンス上の利点を無効にする可能性があることを心配します。

どのようなアプローチをとっていますか(なぜですか)?

答えて

0

任意で属性を使って制御できる2つのインスタンス(左と右)のすべてのプロパティを再帰的に参照し、左から右のequalsメソッドを呼び出す静的メソッドを作成します。プロパティの1つが不等式を示すとき、2つのインスタンスが異なることがわかります。これにより、比較するコード量を最小限に抑えながら、比較対象となるメソッドと比較する方法([NoCompare]のような新しい属性で特定のプロパティをマークし、カスタム等価ロジックを実装することによって)を完全に制御できます。

+0

これは、クラス自身がEqualsを実装し、単純なA == Bチェックを実行するよりも優れているのはなぜですか? – SonOfPirate

+0

@SonOfPirate - これは、いくつかのフィールドをチェックするだけで、あなたの排他的な説明に従って使用される単純なクラスで動作します。デフォルトでは、平等ははるかに複雑なものです。新しいオブジェクト()==新しいオブジェクト()を試してみると、アドレススペースが異なるため(データはまったく同じですが)、falseになることがわかります。クラスの再帰的にプリミティブを比較するメソッドを構築すると、デフォルトの動作に違反することはなく、制御がより簡単になります。 – Polity

+0

実際、Equalsは、アイデンティティの等価性を提供するコードでオーバーライドされるように設計されているため、Equalsは使用するのに最適な方法ではありません。 (例えば、Hashtableでは、2つの項目が等しいかどうかを判断するためにEqualsが使用されます。基本実装を使用すると、参照が同じオブジェクトに対して動作することはめったにないオブジェクトかどうかがチェックされます。つまり、IsaameAsか何か他のものと呼んでも、各オブジェクト内にカプセル化された '等価性'の基準を持つ方が良いと思います。 – SonOfPirate

0

データオブジェクトにequals演算子を指定したと仮定すると、それらが等価であることをチェックするだけで済みます。

例:

CacheEntry<MyItem> cacheEntry = ...; 
    MyItem newItem = ...; 

    if (cacheEntry.Item != newItem) 
    { 
     cacheEntry.item = newItem; 
     cacheEntry.lastUpdated = DateTime.UtcNow; 
    } 

NB:あなたが戻ってあなたの結果を持って次に

class CacheEntry<TCacheItem> 
{ 
    TCacheItem item; 
    DateTime? lastUpated; 
} 

class MyItem 
{ 
    int Id; 
    string Foo; 

    public bool Equals(MyItem b) 
    { 
     return this.Id == b.Id && this.Foo == b.Foo; // or something like this... 
    } 
} 

スレッドの安全性が出て左にチェック。

+0

さて、これは単純なアプローチのようですが、すべてのオブジェクトを比較するためにオブジェクトグラフ全体をクロールする時間が必要です。 – SonOfPirate

+0

私はこの時点までにどちらのオブジェクトも変更されないため、スレッドセーフについては心配していません。 – SonOfPirate

+0

上記の@ Polityの記事をフォローアップすると、ビジターがオブジェクトグラフのクロールを処理するか、またはオブジェクトの子要素の等価性がそれ自身の等価チェックの一部であることを提案しますか? – SonOfPirate

関連する問題