首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在web应用程序中正确使用C#锁

在web应用程序中正确使用C#锁
EN

Stack Overflow用户
提问于 2013-03-06 20:12:32
回答 2查看 2.4K关注 0票数 1

我有一个帮助器类,它读取一个大的XML文档并生成一个c#对象列表。

我经常使用这些对象,所以我认为最好的方法是将它们保存在内存中,然后从内存中访问它们。

我创建了一个简单的存储库,它从内存中获取一个对象,如果不存在,就添加它。

存储库如下所示:

代码语言:javascript
复制
public class XmlDocumentRepository
{
    private readonly ICacheStorage _cacheStorage;
    public XmlDocumentRepository(ICacheStorage cacheStorage)
    {
        _cacheStorage = cacheStorage;
    }

    private readonly object _locker = new object();

    private void DeserializeXmlDocument()
    {
        lock (_locker)
        {
            // I deserialize the xml document, i generate the c# classes, and save them in cache
            IEnumerable<Page> pages = new XmlDeserializerHelper().DeserializeXml();    

            foreach(var page in pages)
            {
                _cacheStorage.Add(page_Id, page);
            }
        }
    }

    public Page GetPage(Guid page_Id)
    {
        Page page = _cacheStorage.Get<Page>(page_Id);
        if (page != null)
            return page;

        lock (_locker)
        {
            page = _cacheStorage.Get<Page>(page_Id);
            if (page != null)
                return page;

            DeserializeXmlDocument();

            page = _cacheStorage.Get<Page>(page_Id);
            return page;
        }
    }
}

XmlDocumentRepository在web应用程序内部使用(更准确地说是asp.net mvc )。

存储库的实现好吗?我是否正确地使用了lock语句?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-06 21:02:09

在我对这个问题的评论中,我误解了共享的缓存。我认为您需要执行以下选项之一:

  • 使锁定对象成为可在所有请求中使用的单一实例,因为锁定对象是私有字段,因此每个请求都将具有具有新字段的存储库的新实例。
  • 使锁定对象成为静态字段,以便在所有XmlDocumentRepository实例之间共享它。
票数 1
EN

Stack Overflow用户

发布于 2013-03-06 20:38:58

作为主要规则,您希望保护对由多个线程使用的数据存储的所有访问变体。我在你的实现中看到了几个潜在的问题;

1: ICacheStorage是从外部提供的,这意味着这个集合可以在其他地方修改,这可能会受到锁的保护,也可能不会。也许您应该要求集合本身使用内部锁定,或者其他类型的线程安全机制?

2:数据访问锁保护不一致。在GetPage中,您在应用锁之前访问_cacheStorage,而在反序列化中,您在锁中访问它。这意味着您可能会得到一个结果,其中一个正在添加到缓存中,而另一个正在从缓存中获取。

3:对于缓存、xml读取,还是两者都要求线程安全?如果只需要保护缓存,那么可以将xml的读取移到锁之外。如果同时保护这两个函数,则应该将整个GetPage函数放入锁中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15247068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档