我有一个函数可以反序列化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
吗?
谢谢
答案 0 :(得分:4)
这在很大程度上取决于具体实施。如果调用的代码与主lock
/ DeserializeXml
在同一个线程上,并且它使用同步版本(OnElementDeserializedCallback(...)
或{{1} }) - 然后它将已经存在于现有锁内,因为锁基本上与线程相关联。
如果实现使用异步实现(OnElementDeserializedCallback.Invoke(...)
,BeginInvoke
,Task
等),那么否:它将不在锁内。
如果不确定,你可以锁定两个地方(因为锁是可重入的,如果你最终从同一个线程中嵌套锁定两次并不重要);但是,如果结果是是异步,但它也会尝试加入回调(ThreadPool
,Delegate.EndInvoke
等)然后它可能完全陷入僵局。