What element does ConcurrentDictionary.ElementAt return











up vote
2
down vote

favorite












In my code I got an ConcurrentDictionary now I want to iterate over each element in the Dictionary, but if a condition is true I want to remove an element from this Dictionary so I can't use a foreach loop. Also it might happen that the Dictionary will get a new element while in the loop or get one removed from a different thread. After some research I ended up using ElementAt.



Now my question is if the ConcurrentDictionary will release the indexes again like a List does. So that the first element will always have the index 0.



This is what my code looks like, CommandHandler.Timeouter is from ConcurrentDictionary:



int current = 0;

while (CommandHandler.Timeouter.Count() > current)
{
var info = CommandHandler.Timeouter.ElementAt(current);
var timeoutcooldown = info.Value.LastCommandTime.AddMinutes(1);

if (timeoutcooldown < DateTime.UtcNow)
{
CommandHandler.Timeouter.TryRemove(info.Key, out _);
}
else current++;
}









share|improve this question


















  • 1




    Note that dictionaries do not guarantee a certain sequential order of elements (or key-value-pairs, for that matter). In other words, the order of elements in dictionaries is non-deterministic. If you ask whether an element at index 0 (as used by the Linq extension method ElementAt) will always stay at index 0, then no, this is not guaranteed...
    – elgonzo
    Nov 11 at 10:05












  • Well this is bad.I guess I might end up using a List and using Linq to search for what I need.
    – Twenty
    Nov 11 at 10:07






  • 2




    You can iterate just fine through a ConcurrentDictionary (see here: stackoverflow.com/questions/17776422/…). If new elements are added to the ConcurrentDictionary by some other thread during an iteration then they might not be part of the iteration. But that isn't a problem as such new elements would then be subject of the next clean-up iteration a few minutes later. (1/2)
    – elgonzo
    Nov 11 at 10:19






  • 1




    (2/2) ConcurrentDictionary also allow removal of elements within an iteration loop using ConcurrentDictionary.TryRemove (see here: stackoverflow.com/questions/2318005/…). See, StackOverflow has all the answers ;-)
    – elgonzo
    Nov 11 at 10:19








  • 2




    Yes, but keep in mind to use ONLY methods provided by ConcurrentDictionary itself. No Linq or other extension methods! (because ConcurrentDictionary can ensure thread safety only with regard to its own methods)
    – elgonzo
    Nov 11 at 10:21

















up vote
2
down vote

favorite












In my code I got an ConcurrentDictionary now I want to iterate over each element in the Dictionary, but if a condition is true I want to remove an element from this Dictionary so I can't use a foreach loop. Also it might happen that the Dictionary will get a new element while in the loop or get one removed from a different thread. After some research I ended up using ElementAt.



Now my question is if the ConcurrentDictionary will release the indexes again like a List does. So that the first element will always have the index 0.



This is what my code looks like, CommandHandler.Timeouter is from ConcurrentDictionary:



int current = 0;

while (CommandHandler.Timeouter.Count() > current)
{
var info = CommandHandler.Timeouter.ElementAt(current);
var timeoutcooldown = info.Value.LastCommandTime.AddMinutes(1);

if (timeoutcooldown < DateTime.UtcNow)
{
CommandHandler.Timeouter.TryRemove(info.Key, out _);
}
else current++;
}









share|improve this question


















  • 1




    Note that dictionaries do not guarantee a certain sequential order of elements (or key-value-pairs, for that matter). In other words, the order of elements in dictionaries is non-deterministic. If you ask whether an element at index 0 (as used by the Linq extension method ElementAt) will always stay at index 0, then no, this is not guaranteed...
    – elgonzo
    Nov 11 at 10:05












  • Well this is bad.I guess I might end up using a List and using Linq to search for what I need.
    – Twenty
    Nov 11 at 10:07






  • 2




    You can iterate just fine through a ConcurrentDictionary (see here: stackoverflow.com/questions/17776422/…). If new elements are added to the ConcurrentDictionary by some other thread during an iteration then they might not be part of the iteration. But that isn't a problem as such new elements would then be subject of the next clean-up iteration a few minutes later. (1/2)
    – elgonzo
    Nov 11 at 10:19






  • 1




    (2/2) ConcurrentDictionary also allow removal of elements within an iteration loop using ConcurrentDictionary.TryRemove (see here: stackoverflow.com/questions/2318005/…). See, StackOverflow has all the answers ;-)
    – elgonzo
    Nov 11 at 10:19








  • 2




    Yes, but keep in mind to use ONLY methods provided by ConcurrentDictionary itself. No Linq or other extension methods! (because ConcurrentDictionary can ensure thread safety only with regard to its own methods)
    – elgonzo
    Nov 11 at 10:21















up vote
2
down vote

favorite









up vote
2
down vote

favorite











In my code I got an ConcurrentDictionary now I want to iterate over each element in the Dictionary, but if a condition is true I want to remove an element from this Dictionary so I can't use a foreach loop. Also it might happen that the Dictionary will get a new element while in the loop or get one removed from a different thread. After some research I ended up using ElementAt.



Now my question is if the ConcurrentDictionary will release the indexes again like a List does. So that the first element will always have the index 0.



This is what my code looks like, CommandHandler.Timeouter is from ConcurrentDictionary:



int current = 0;

while (CommandHandler.Timeouter.Count() > current)
{
var info = CommandHandler.Timeouter.ElementAt(current);
var timeoutcooldown = info.Value.LastCommandTime.AddMinutes(1);

if (timeoutcooldown < DateTime.UtcNow)
{
CommandHandler.Timeouter.TryRemove(info.Key, out _);
}
else current++;
}









share|improve this question













In my code I got an ConcurrentDictionary now I want to iterate over each element in the Dictionary, but if a condition is true I want to remove an element from this Dictionary so I can't use a foreach loop. Also it might happen that the Dictionary will get a new element while in the loop or get one removed from a different thread. After some research I ended up using ElementAt.



Now my question is if the ConcurrentDictionary will release the indexes again like a List does. So that the first element will always have the index 0.



This is what my code looks like, CommandHandler.Timeouter is from ConcurrentDictionary:



int current = 0;

while (CommandHandler.Timeouter.Count() > current)
{
var info = CommandHandler.Timeouter.ElementAt(current);
var timeoutcooldown = info.Value.LastCommandTime.AddMinutes(1);

if (timeoutcooldown < DateTime.UtcNow)
{
CommandHandler.Timeouter.TryRemove(info.Key, out _);
}
else current++;
}






c# multithreading concurrentdictionary






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 10:01









Twenty

31014




31014








  • 1




    Note that dictionaries do not guarantee a certain sequential order of elements (or key-value-pairs, for that matter). In other words, the order of elements in dictionaries is non-deterministic. If you ask whether an element at index 0 (as used by the Linq extension method ElementAt) will always stay at index 0, then no, this is not guaranteed...
    – elgonzo
    Nov 11 at 10:05












  • Well this is bad.I guess I might end up using a List and using Linq to search for what I need.
    – Twenty
    Nov 11 at 10:07






  • 2




    You can iterate just fine through a ConcurrentDictionary (see here: stackoverflow.com/questions/17776422/…). If new elements are added to the ConcurrentDictionary by some other thread during an iteration then they might not be part of the iteration. But that isn't a problem as such new elements would then be subject of the next clean-up iteration a few minutes later. (1/2)
    – elgonzo
    Nov 11 at 10:19






  • 1




    (2/2) ConcurrentDictionary also allow removal of elements within an iteration loop using ConcurrentDictionary.TryRemove (see here: stackoverflow.com/questions/2318005/…). See, StackOverflow has all the answers ;-)
    – elgonzo
    Nov 11 at 10:19








  • 2




    Yes, but keep in mind to use ONLY methods provided by ConcurrentDictionary itself. No Linq or other extension methods! (because ConcurrentDictionary can ensure thread safety only with regard to its own methods)
    – elgonzo
    Nov 11 at 10:21
















  • 1




    Note that dictionaries do not guarantee a certain sequential order of elements (or key-value-pairs, for that matter). In other words, the order of elements in dictionaries is non-deterministic. If you ask whether an element at index 0 (as used by the Linq extension method ElementAt) will always stay at index 0, then no, this is not guaranteed...
    – elgonzo
    Nov 11 at 10:05












  • Well this is bad.I guess I might end up using a List and using Linq to search for what I need.
    – Twenty
    Nov 11 at 10:07






  • 2




    You can iterate just fine through a ConcurrentDictionary (see here: stackoverflow.com/questions/17776422/…). If new elements are added to the ConcurrentDictionary by some other thread during an iteration then they might not be part of the iteration. But that isn't a problem as such new elements would then be subject of the next clean-up iteration a few minutes later. (1/2)
    – elgonzo
    Nov 11 at 10:19






  • 1




    (2/2) ConcurrentDictionary also allow removal of elements within an iteration loop using ConcurrentDictionary.TryRemove (see here: stackoverflow.com/questions/2318005/…). See, StackOverflow has all the answers ;-)
    – elgonzo
    Nov 11 at 10:19








  • 2




    Yes, but keep in mind to use ONLY methods provided by ConcurrentDictionary itself. No Linq or other extension methods! (because ConcurrentDictionary can ensure thread safety only with regard to its own methods)
    – elgonzo
    Nov 11 at 10:21










1




1




Note that dictionaries do not guarantee a certain sequential order of elements (or key-value-pairs, for that matter). In other words, the order of elements in dictionaries is non-deterministic. If you ask whether an element at index 0 (as used by the Linq extension method ElementAt) will always stay at index 0, then no, this is not guaranteed...
– elgonzo
Nov 11 at 10:05






Note that dictionaries do not guarantee a certain sequential order of elements (or key-value-pairs, for that matter). In other words, the order of elements in dictionaries is non-deterministic. If you ask whether an element at index 0 (as used by the Linq extension method ElementAt) will always stay at index 0, then no, this is not guaranteed...
– elgonzo
Nov 11 at 10:05














Well this is bad.I guess I might end up using a List and using Linq to search for what I need.
– Twenty
Nov 11 at 10:07




Well this is bad.I guess I might end up using a List and using Linq to search for what I need.
– Twenty
Nov 11 at 10:07




2




2




You can iterate just fine through a ConcurrentDictionary (see here: stackoverflow.com/questions/17776422/…). If new elements are added to the ConcurrentDictionary by some other thread during an iteration then they might not be part of the iteration. But that isn't a problem as such new elements would then be subject of the next clean-up iteration a few minutes later. (1/2)
– elgonzo
Nov 11 at 10:19




You can iterate just fine through a ConcurrentDictionary (see here: stackoverflow.com/questions/17776422/…). If new elements are added to the ConcurrentDictionary by some other thread during an iteration then they might not be part of the iteration. But that isn't a problem as such new elements would then be subject of the next clean-up iteration a few minutes later. (1/2)
– elgonzo
Nov 11 at 10:19




1




1




(2/2) ConcurrentDictionary also allow removal of elements within an iteration loop using ConcurrentDictionary.TryRemove (see here: stackoverflow.com/questions/2318005/…). See, StackOverflow has all the answers ;-)
– elgonzo
Nov 11 at 10:19






(2/2) ConcurrentDictionary also allow removal of elements within an iteration loop using ConcurrentDictionary.TryRemove (see here: stackoverflow.com/questions/2318005/…). See, StackOverflow has all the answers ;-)
– elgonzo
Nov 11 at 10:19






2




2




Yes, but keep in mind to use ONLY methods provided by ConcurrentDictionary itself. No Linq or other extension methods! (because ConcurrentDictionary can ensure thread safety only with regard to its own methods)
– elgonzo
Nov 11 at 10:21






Yes, but keep in mind to use ONLY methods provided by ConcurrentDictionary itself. No Linq or other extension methods! (because ConcurrentDictionary can ensure thread safety only with regard to its own methods)
– elgonzo
Nov 11 at 10:21














1 Answer
1






active

oldest

votes

















up vote
2
down vote













ElementAt just treats the dictionary as an IEnumerable<KeyValuePair<TKey, TValue>>. Dictionaries are not ordered. The index is therefore meaningless. Think of the elements coming back in random order each time. Also, ElementAt has no way to make this thread safe.



It seems you want to implement cache expiration. Consider just using lock to access a normal dictionary. If there is not much contention this will be the simplest solution and very fast.



An alternative code pattern to this loop would be this:



var itemsToExpire = myDict.Where(/* compute expiration */).ToList();
foreach (var item in itemsToExpire)
myDict.Remove(item);


No need for any complicated looping.






share|improve this answer





















  • Thanks a lot for the answer, since elgonzo already guided me, I will not mark this as answer but an upvote for sure. Thanks!
    – Twenty
    Nov 11 at 10:24











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53247606%2fwhat-element-does-concurrentdictionary-elementat-return%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote













ElementAt just treats the dictionary as an IEnumerable<KeyValuePair<TKey, TValue>>. Dictionaries are not ordered. The index is therefore meaningless. Think of the elements coming back in random order each time. Also, ElementAt has no way to make this thread safe.



It seems you want to implement cache expiration. Consider just using lock to access a normal dictionary. If there is not much contention this will be the simplest solution and very fast.



An alternative code pattern to this loop would be this:



var itemsToExpire = myDict.Where(/* compute expiration */).ToList();
foreach (var item in itemsToExpire)
myDict.Remove(item);


No need for any complicated looping.






share|improve this answer





















  • Thanks a lot for the answer, since elgonzo already guided me, I will not mark this as answer but an upvote for sure. Thanks!
    – Twenty
    Nov 11 at 10:24















up vote
2
down vote













ElementAt just treats the dictionary as an IEnumerable<KeyValuePair<TKey, TValue>>. Dictionaries are not ordered. The index is therefore meaningless. Think of the elements coming back in random order each time. Also, ElementAt has no way to make this thread safe.



It seems you want to implement cache expiration. Consider just using lock to access a normal dictionary. If there is not much contention this will be the simplest solution and very fast.



An alternative code pattern to this loop would be this:



var itemsToExpire = myDict.Where(/* compute expiration */).ToList();
foreach (var item in itemsToExpire)
myDict.Remove(item);


No need for any complicated looping.






share|improve this answer





















  • Thanks a lot for the answer, since elgonzo already guided me, I will not mark this as answer but an upvote for sure. Thanks!
    – Twenty
    Nov 11 at 10:24













up vote
2
down vote










up vote
2
down vote









ElementAt just treats the dictionary as an IEnumerable<KeyValuePair<TKey, TValue>>. Dictionaries are not ordered. The index is therefore meaningless. Think of the elements coming back in random order each time. Also, ElementAt has no way to make this thread safe.



It seems you want to implement cache expiration. Consider just using lock to access a normal dictionary. If there is not much contention this will be the simplest solution and very fast.



An alternative code pattern to this loop would be this:



var itemsToExpire = myDict.Where(/* compute expiration */).ToList();
foreach (var item in itemsToExpire)
myDict.Remove(item);


No need for any complicated looping.






share|improve this answer












ElementAt just treats the dictionary as an IEnumerable<KeyValuePair<TKey, TValue>>. Dictionaries are not ordered. The index is therefore meaningless. Think of the elements coming back in random order each time. Also, ElementAt has no way to make this thread safe.



It seems you want to implement cache expiration. Consider just using lock to access a normal dictionary. If there is not much contention this will be the simplest solution and very fast.



An alternative code pattern to this loop would be this:



var itemsToExpire = myDict.Where(/* compute expiration */).ToList();
foreach (var item in itemsToExpire)
myDict.Remove(item);


No need for any complicated looping.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 11 at 10:20









usr

143k25185297




143k25185297












  • Thanks a lot for the answer, since elgonzo already guided me, I will not mark this as answer but an upvote for sure. Thanks!
    – Twenty
    Nov 11 at 10:24


















  • Thanks a lot for the answer, since elgonzo already guided me, I will not mark this as answer but an upvote for sure. Thanks!
    – Twenty
    Nov 11 at 10:24
















Thanks a lot for the answer, since elgonzo already guided me, I will not mark this as answer but an upvote for sure. Thanks!
– Twenty
Nov 11 at 10:24




Thanks a lot for the answer, since elgonzo already guided me, I will not mark this as answer but an upvote for sure. Thanks!
– Twenty
Nov 11 at 10:24


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53247606%2fwhat-element-does-concurrentdictionary-elementat-return%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python