{"action":"created","issue":{"url":"https://api.github.com/repos/NLog/NLog/issues/934","labels_url":"https://api.github.com/repos/NLog/NLog/issues/934/labels{/name}","comments_url":"https://api.github.com/repos/NLog/NLog/issues/934/comments","events_url":"https://api.github.com/repos/NLog/NLog/issues/934/events","html_url":"https://github.com/NLog/NLog/issues/934","id":108830047,"number":934,"title":"MDLC implementation uses mutable dictionary which causes reference updates between threads","user":{"login":"Fresa","id":1190300,"avatar_url":"https://avatars.githubusercontent.com/u/1190300?v=3","gravatar_id":"","url":"https://api.github.com/users/Fresa","html_url":"https://github.com/Fresa","followers_url":"https://api.github.com/users/Fresa/followers","following_url":"https://api.github.com/users/Fresa/following{/other_user}","gists_url":"https://api.github.com/users/Fresa/gists{/gist_id}","starred_url":"https://api.github.com/users/Fresa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Fresa/subscriptions","organizations_url":"https://api.github.com/users/Fresa/orgs","repos_url":"https://api.github.com/users/Fresa/repos","events_url":"https://api.github.com/users/Fresa/events{/privacy}","received_events_url":"https://api.github.com/users/Fresa/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/NLog/NLog/labels/bug","name":"bug","color":"fc2929"}],"state":"open","locked":false,"assignee":{"login":"UgurAldanmaz","id":5686267,"avatar_url":"https://avatars.githubusercontent.com/u/5686267?v=3","gravatar_id":"","url":"https://api.github.com/users/UgurAldanmaz","html_url":"https://github.com/UgurAldanmaz","followers_url":"https://api.github.com/users/UgurAldanmaz/followers","following_url":"https://api.github.com/users/UgurAldanmaz/following{/other_user}","gists_url":"https://api.github.com/users/UgurAldanmaz/gists{/gist_id}","starred_url":"https://api.github.com/users/UgurAldanmaz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/UgurAldanmaz/subscriptions","organizations_url":"https://api.github.com/users/UgurAldanmaz/orgs","repos_url":"https://api.github.com/users/UgurAldanmaz/repos","events_url":"https://api.github.com/users/UgurAldanmaz/events{/privacy}","received_events_url":"https://api.github.com/users/UgurAldanmaz/received_events","type":"User","site_admin":false},"milestone":null,"comments":10,"created_at":"2015-09-29T09:23:09Z","updated_at":"2015-11-16T13:35:38Z","closed_at":null,"body":"The MDLC implementation (MappedDiagnosticsLogicalContext.cs) uses a mutable dictionary which causes reference updates between threads since CallContext uses shallow copy when flagged as write on copy during thread/task delegation. It basically means that an update of a value in a child thread will also update the value in the parent thread, which should not be the expected behavior.\r\n\r\nYou should consider using a immutable dictionary. Or why not use the CallContext directly by prefixing the items with the dictionary key? That will be more effective than recreating a dictionary every time a change needs to occur. \r\n\r\nI refer to the great CallContext post created by Mr Cleary explaining this even further. http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html\r\n\r\nAlso, allowing object types to be inserted is a potential problem since CallContext.LogicalSetData requires the data to be marked as Serializable or it will throw an exception. See parameters description at https://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.callcontext.logicalsetdata(v=vs.110).aspx\r\n\r\nI give you an example of how you con simplify the implementation and get rid of the above problems. It lacks the Contains, Remove and Clear methods but they should be fairly simple to implement.\r\n\r\n\r\n    public static class LogicalThreadContext  \r\n    { \r\n        private const string KeyPrefix = \"NLog.LogicalThreadContext\"; \r\n\r\n        private static string GetCallContextKey(string key)\r\n        {\r\n            return string.Format(\"{0}.{1}\", KeyPrefix, key);\r\n        }\r\n\r\n        private static string GetCallContextValue(string key)\r\n        {\r\n            return CallContext.LogicalGetData(GetCallContextKey(key)) as string ?? string.Empty;\r\n        }\r\n\r\n        private static void SetCallContextValue(string key, string value)\r\n        {\r\n            CallContext.LogicalSetData(GetCallContextKey(key), value);         \r\n        }\r\n\r\n        public static string Get(string item)\r\n        {\r\n            return GetCallContextValue(item);\r\n        }\r\n\r\n        public static string Get(string item, IFormatProvider formatProvider)\r\n        {\r\n            if ((formatProvider == null) && (LogManager.Configuration != null))\r\n            {\r\n                formatProvider = LogManager.Configuration.DefaultCultureInfo;\r\n            }\r\n\r\n            return string.Format(formatProvider, \"{0}\", GetCallContextValue(item));\r\n        }\r\n        \r\n        public static void Set(string item, string value)\r\n        {\r\n            SetCallContextValue(item, value);\r\n        }\r\n    }"},"comment":{"url":"https://api.github.com/repos/NLog/NLog/issues/comments/157028155","html_url":"https://github.com/NLog/NLog/issues/934#issuecomment-157028155","issue_url":"https://api.github.com/repos/NLog/NLog/issues/934","id":157028155,"user":{"login":"304NotModified","id":5808377,"avatar_url":"https://avatars.githubusercontent.com/u/5808377?v=3","gravatar_id":"","url":"https://api.github.com/users/304NotModified","html_url":"https://github.com/304NotModified","followers_url":"https://api.github.com/users/304NotModified/followers","following_url":"https://api.github.com/users/304NotModified/following{/other_user}","gists_url":"https://api.github.com/users/304NotModified/gists{/gist_id}","starred_url":"https://api.github.com/users/304NotModified/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/304NotModified/subscriptions","organizations_url":"https://api.github.com/users/304NotModified/orgs","repos_url":"https://api.github.com/users/304NotModified/repos","events_url":"https://api.github.com/users/304NotModified/events{/privacy}","received_events_url":"https://api.github.com/users/304NotModified/received_events","type":"User","site_admin":false},"created_at":"2015-11-16T13:35:38Z","updated_at":"2015-11-16T13:35:38Z","body":"just a 4.x release. So if we can fix the new GDC and MDC (with new names, see #886), and then the new MDLC (need also new name), then I will merge it into 4.3 or 4.4"}}