首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有locked属性的c# foreach

具有locked属性的c# foreach
EN

Stack Overflow用户
提问于 2012-01-08 08:20:08
回答 6查看 3.4K关注 0票数 1

好的,这就是我的财产

代码语言:javascript
复制
public List<String> names{
    get{
        lock(_names)
            return _names;
       }
   set{
       lock(_names)
           _names = value
      }
}
private List<String> _names;

现在假设我对像这样的名字做了个foreach

代码语言:javascript
复制
foreach(String s in names)
{
    Console.WriteLine(s);
}

我的问题是,names是在整个foreach中锁定的,还是只在每次设置s时锁定lock,然后在foreach中解锁。

如果这让人困惑,假设我试着这样做

代码语言:javascript
复制
foreach(String s in names)
{
    lock(names)
        Console.WriteLine(s);
}

我会陷入僵局吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-01-08 08:23:33

get_Names方法将只被调用一次,并且在项的迭代期间锁将结束(将会有no锁)。这可能不是您想要的,您可能应该使用更细粒度的锁,例如:

代码语言:javascript
复制
lock (someLockObject)
{
    foreach(String s in names)
    {
        Console.WriteLine(s);
    }
}

当您在循环中锁定时,您将一个接一个地获取多个锁,这几乎肯定不是您想要的,因为操作foreach循环将不再是原子的。

票数 2
EN

Stack Overflow用户

发布于 2012-01-08 08:26:26

代码语言:javascript
复制
lock(_names) return _names;

简写为:

代码语言:javascript
复制
try
{
  Monitor.Enter(_names);
  return _names;
}
finally
{
  Monitor.Exit(_names);
}

这相当于:

代码语言:javascript
复制
Monitor.Enter(_names);
Monitor.Exit(_names);
return _names;

从这个角度来看,应该更清楚地表明锁是不必要的。您可能会对使用其中一个thread-safe collections感兴趣

票数 4
EN

Stack Overflow用户

发布于 2012-01-08 08:23:11

它不是锁在foreach里面的。它被锁定了一次,以get一个引用,然后迭代。(此外,属性内的lock语句目前是不必要的;这些操作是原子的。)

最有可能的情况是,您应该锁定循环体之外的位置,以及修改集合的位置。

对于您的编辑,请不要。这不是一个并行的foreach,所以循环不可能自己卡住,更不用说死锁了。再说一次,这只会浪费处理能力。

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

https://stackoverflow.com/questions/8774314

复制
相关文章

相似问题

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