2012-11-08 28 views
4

我有一個反序列化Xml文檔並從中創建對象的函數。C#:lock語句中的回調函數是否也被鎖定?

我想將對象存儲到緩存中,所以我不需要每次需要從中獲取數據時反序列化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") 

我的問題是,我應該使用lockOnElementDeserializedCallback回調裏面呢?

謝謝

回答

4

這取決於具體的實施。如果調用該代碼的代碼與主代碼lock/DeserializeXml位於同一個線程中,並且它使用同步版版本(OnElementDeserializedCallback(...)OnElementDeserializedCallback.Invoke(...)),那麼它將已經在現有的鎖內,因爲鎖基本上與線。

如果實現使用異步實現(BeginInvokeTaskThreadPool等),則不:它會是鎖內。

如果不確定,你可以在兩個地方鎖定(因爲鎖是可重入的,如果你最終從同一個線程獲得兩次嵌套鎖定沒有關係)。然而,如果它發現它異步,但它也然後嘗試回調(Delegate.EndInvoke,Task.Wait,等),然後它可能完全死鎖。

+0

我會雙鎖只是爲了確保它鎖定:) – Catalin

+1

完全死鎖:) – flindeberg

相關問題