4

Xml ドキュメントを逆シリアル化し、そこからオブジェクトを作成する関数があります。

オブジェクトをキャッシュに保存して、xml からデータを取得する必要があるたびに xml を逆シリアル化する必要がないようにします。

public class XMLDeserializer
{
    public event OnElementDeserialized OnElementDeserializedCallback;

    public void DeserializeXml(string xmlPath)
    {
        // implementation
    }
}

public class XMLDeserializerFacade
{
    private static object _lockObject = new object();

    private XMLDeserializer xmlDeserializer;
    private ICacheProvider cacheProvider;
    public XMLDeserializerFacade(XMLDeserializer xmlDeserializer, ICacheProvider cacheProvider)
    {
        this.xmlDeserializer = xmlDeserializer;
        this.cacheProvider = cacheProvider;

        xmlDeserializer.OnElementDeserializedCallback += delegate(object element)
        {
            cacheProvider.Add("uniqueKey", element);
            // is here in lock as well or i have to lock it again?
        };
    }

    public void DeserializeXml(string xmlPath)
    {
        lock(_lockObject)
        {
            xmlDeserializer.DeserializeXml(xmlPath);

            // From here it will go to
            // cacheProvider.Add("uniqueKey", element);  callback
        }
    }
}

XMLをデシリアライズしたいときは、

XMLDeserializerFacade.DeserializeXml("file.xml")

私の質問は、コールバックlock内でも使用する必要があるということですか?OnElementDeserializedCallback

ありがとうございました

4

1 に答える 1

4

それは特定の実装に大きく依存します。lockそれを呼び出すコードがメインの/と同じスレッド上にあり、同期バージョン (または)DeserializeXmlを使用している場合、ロックは本質的にスレッドに関連付けられているため、既に既存のロック内にあります。OnElementDeserializedCallback(...)OnElementDeserializedCallback.Invoke(...)

実装が非同期実装 ( BeginInvoke、など) を使用している場合TaskThreadPoolいいえ:ロック内にはありません。

不明な場合は、両方の場所でロックできます (ロックは再入可能であるため、同じスレッドから 2 回ネストされたロックになっても問題ありません)。ただし、非同期であることが判明した場合でも、コールバック ( 、 など) に参加しようとすると、完全にデッドロックする可能性があります。Delegate.EndInvokeTask.Wait

于 2012-11-08T10:35:03.360 に答える