{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/corefx/issues/2338","labels_url":"https://api.github.com/repos/dotnet/corefx/issues/2338/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/2338/comments","events_url":"https://api.github.com/repos/dotnet/corefx/issues/2338/events","html_url":"https://github.com/dotnet/corefx/issues/2338","id":94802002,"number":2338,"title":"Add ConcurrentBag<T> Clear method","user":{"login":"MarkusSintonen","id":12939780,"avatar_url":"https://avatars.githubusercontent.com/u/12939780?v=3","gravatar_id":"","url":"https://api.github.com/users/MarkusSintonen","html_url":"https://github.com/MarkusSintonen","followers_url":"https://api.github.com/users/MarkusSintonen/followers","following_url":"https://api.github.com/users/MarkusSintonen/following{/other_user}","gists_url":"https://api.github.com/users/MarkusSintonen/gists{/gist_id}","starred_url":"https://api.github.com/users/MarkusSintonen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MarkusSintonen/subscriptions","organizations_url":"https://api.github.com/users/MarkusSintonen/orgs","repos_url":"https://api.github.com/users/MarkusSintonen/repos","events_url":"https://api.github.com/users/MarkusSintonen/events{/privacy}","received_events_url":"https://api.github.com/users/MarkusSintonen/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-07-13T20:17:31Z","updated_at":"2015-07-13T20:29:55Z","closed_at":null,"body":"Currently `ConcurrentBag<T>` does not support clearing of the bag. Currently only way to clear the bag is to call `TryTake` in a loop which is suboptimal in high concurrency applications:\r\n````CSharp\r\nT dummy;\r\nwhile(bag.TryTake(out dummy)) {}\r\n````\r\n\r\nInstead `Clear` method could be implemented so that the bag is emptied at once. Here is the proposed implementation:\r\n````CSharp\r\npublic void Clear()\r\n{\r\n\t// Short path if the bag is empty\r\n\tif (_headList == null)\r\n\t\treturn;\r\n\r\n\tbool lockTaken = false;\r\n\ttry\r\n\t{\r\n\t\tFreezeBag(ref lockTaken);\r\n\r\n\t\tThreadLocalList currentList = _headList;\r\n\t\twhile (currentList != null)\r\n\t\t{\r\n\t\t\tcurrentList.Reset();\r\n\t\t\tcurrentList = currentList._nextList;\r\n\t\t}\r\n\t}\r\n\tfinally\r\n\t{\r\n\t\tUnfreezeBag(lockTaken);\r\n\t}\r\n}\r\n````\r\n\r\nInternal class `ThreadLocalList` needs new `Reset/Invalidate` method which sets the thread specific linked list _head and _tail to null as well as resets the counters. GC would then collect the non referenced linked list nodes.\r\n````CSharp\r\ninternal void Reset()\r\n{\r\n\t_head = null;\r\n\t_tail = null;\r\n\t_count = 0;\r\n\t_stealCount = 0;\r\n\t_version = 0; // Reset version since the local list is empty again (to be consistent with class comments)\r\n}\r\n````\r\n\r\n`Clear` would lock the bag for the duration of the operation since it could cause undefined behaviour  if other threads would access the bag while linked lists are being reseted. (Similarly ConcurrentDictionary<K,T> also locks the dictionary when `Clear` is called.)"},"comment":{"url":"https://api.github.com/repos/dotnet/corefx/issues/comments/121047155","html_url":"https://github.com/dotnet/corefx/issues/2338#issuecomment-121047155","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/2338","id":121047155,"user":{"login":"stephentoub","id":2642209,"avatar_url":"https://avatars.githubusercontent.com/u/2642209?v=3","gravatar_id":"","url":"https://api.github.com/users/stephentoub","html_url":"https://github.com/stephentoub","followers_url":"https://api.github.com/users/stephentoub/followers","following_url":"https://api.github.com/users/stephentoub/following{/other_user}","gists_url":"https://api.github.com/users/stephentoub/gists{/gist_id}","starred_url":"https://api.github.com/users/stephentoub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephentoub/subscriptions","organizations_url":"https://api.github.com/users/stephentoub/orgs","repos_url":"https://api.github.com/users/stephentoub/repos","events_url":"https://api.github.com/users/stephentoub/events{/privacy}","received_events_url":"https://api.github.com/users/stephentoub/received_events","type":"User","site_admin":false},"created_at":"2015-07-13T20:29:55Z","updated_at":"2015-07-13T20:29:55Z","body":"Thanks, @MarkusSintonen.  Can you share some specific examples for where such a ```Clear``` method would be valuable?"}}