Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在并发收集中使用yield_C#_Multithreading_Yield Return_Concurrentdictionary - Fatal编程技术网

C# 在并发收集中使用yield

C# 在并发收集中使用yield,c#,multithreading,yield-return,concurrentdictionary,C#,Multithreading,Yield Return,Concurrentdictionary,这是我之前讨论过的另一个问题,但是我很好奇在使用并发字典和yield功能时,在下面的情况下会发生什么 IEnumerable<int> GetValuesNotZero() { foreach(int value in dictionary.Values) { if(value != 0) { yield return value; } } } IEnumerable GetValues

这是我之前讨论过的另一个问题,但是我很好奇在使用并发字典和yield功能时,在下面的情况下会发生什么

IEnumerable<int> GetValuesNotZero()
{
    foreach(int value in dictionary.Values)
    {
        if(value != 0)
        {
            yield return value;
        }
    }
}
IEnumerable GetValuesNotZero()
{
foreach(dictionary.Values中的int值)
{
如果(值!=0)
{
收益回报值;
}
}
}

如果另一个线程从字典中添加/删除/更新,那么foreach循环中的值会发生什么变化?在我迭代字典时,字典是否被锁定,或者我是否仍有丢失添加/删除/更新值的风险?

在您迭代时,如果另一个线程修改了字典,您将发现更新的值而不是异常(使用普通
字典

如果您还没有到达修改过的项目,您最终将遍历它;否则,如果您已经访问了更新的元素,则可能会错过更新的值

从字典返回的枚举数可以安全使用 同时读取和写入字典,但是 不代表字典的即时快照。这个 通过枚举器公开的内容可能包含所做的修改 在调用GetEnumerator后将其添加到字典

例如,假设Thread1正在遍历字典,而字典现在位于位置3。如果Thread2在位置7处修改了元素,您将找到修改后的值。另一方面,如果它修改了位置1处的元素,您将不会注意到它。(忘记字典是无序的;位置是用来更好地理解的)



我刚刚意识到您的代码在
字典.Values中循环(感谢@Svick在评论中提及);以上答案只有在你翻阅字典时才是正确的。当您在
属性中迭代值时,实际上是在快照中循环。如果词典同时更新,你不会注意到的。

非常感谢,这正是我想要的!但是所讨论的代码不是在迭代字典,而是在迭代
@svick谢谢。更新了我的答案。原来
Values
property只返回一个快照。啊,好吧,如果我使用键/值迭代,我保证会得到一个快照,但是如果我迭代整个集合,则不保证。这真是个好消息!我希望使用并发集合来发挥我的优势,而不是锁定和无法使用收益回报来发挥我的优势。Yield优于常规方法,即创建本地副本然后返回其元素?@ShaffDaddy这是一个实现细节,Keys/Values属性返回快照。这是可以更改的(因为我找不到它的doucmentation)。所以,不要依赖于这种行为。您可以依赖的是线程安全性,而不是您获得的数据。产量并不优越;如果您也使用
foreach
对其进行迭代,则其行为是相同的。