C #: Are callback functions locked inside the lock statement?

I have a function that deserializes an Xml document and creates objects from it.

I want the objects to be cached, so I don't need to deserialize xml every time I need to get data from it.

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 } } } 

When I want to deserialize xml, I call

 XMLDeserializerFacade.DeserializeXml("file.xml") 

My question is, should I use lock also inside the OnElementDeserializedCallback ?

thanks

+4
source share
1 answer

It depends on the specific implementation. If the calling code is in the same stream as the main lock / DeserializeXml , and it uses the synchronous version ( OnElementDeserializedCallback(...) or OnElementDeserializedCallback.Invoke(...) ), then it will already be inside the existing lock, because the lock by essentially connected to the flow.

If the implementation uses an asynchronous implementation ( BeginInvoke , Task , ThreadPool , etc.), then no: it will not be inside the lock.

If you are not sure, you can block both places (since the locks are repeated, it doesnโ€™t matter if you eventually double-locked the lock from the same thread); however, if it turns out that it is asynchronous, but then tries to join the callback ( Delegate.EndInvoke , Task.Wait , etc.), then it may completely go into a dead end.

+4
source

Source: https://habr.com/ru/post/1444767/


All Articles