{"action":"closed","issue":{"url":"https://api.github.com/repos/mikehadlow/EasyNetQ/issues/288","labels_url":"https://api.github.com/repos/mikehadlow/EasyNetQ/issues/288/labels{/name}","comments_url":"https://api.github.com/repos/mikehadlow/EasyNetQ/issues/288/comments","events_url":"https://api.github.com/repos/mikehadlow/EasyNetQ/issues/288/events","html_url":"https://github.com/mikehadlow/EasyNetQ/issues/288","id":45308663,"number":288,"title":"DefaultConsumerErrorStrategy not thread-safe","user":{"login":"noxhoej","id":496242,"avatar_url":"https://avatars.githubusercontent.com/u/496242?v=3","gravatar_id":"","url":"https://api.github.com/users/noxhoej","html_url":"https://github.com/noxhoej","followers_url":"https://api.github.com/users/noxhoej/followers","following_url":"https://api.github.com/users/noxhoej/following{/other_user}","gists_url":"https://api.github.com/users/noxhoej/gists{/gist_id}","starred_url":"https://api.github.com/users/noxhoej/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/noxhoej/subscriptions","organizations_url":"https://api.github.com/users/noxhoej/orgs","repos_url":"https://api.github.com/users/noxhoej/repos","events_url":"https://api.github.com/users/noxhoej/events{/privacy}","received_events_url":"https://api.github.com/users/noxhoej/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2014-10-08T23:07:08Z","updated_at":"2015-01-08T10:05:56Z","closed_at":"2015-01-08T10:05:56Z","body":"Hi\r\n\r\nI have had a problem with a service (which is using EasyNetQ) which does not shut down properly. After quite a bit of debugging, it turns out that the problem is, that [`DefaultConsumerErrorStrategy`](https://github.com/mikehadlow/EasyNetQ/blob/master/Source/EasyNetQ/Consumer/DefaultConsumerErrorStrategy.cs) is not thread-safe. This is a problem, since all EasyNetQ services are registered as singletons.\r\n\r\nThe problem manifests itself when several threads simultaneously call `DefaultConsumerErrorStrategy.HandleConsumerError()`, which again calls `DefaultConsumerErrorStrategy.Connect()`. If `DefaultConsumerErrorStrategy` hasn't yet opened a connection, both threads will end up calling `connectionFactory.CreateConnection()`, each opening a new RabbitMQ.Client connection with three attached threads (MainLoop, HeartbeatReadLoop, and HeartbeatWriteLoop). But only _one_ of these connections end up being stored in `DefaultConsumerErrorStrategy.connection` - and therefore later Disposed(). The other connection will happily live on, with its three threads keeping the process alive...\r\n\r\nSo I think you need to put a `lock` inside `DefaultConsumerErrorStrategy.Connect()`, such that only _one_ thread at a time is allowed.\r\n\r\nI have made a pull request with the proposed fix: https://github.com/mikehadlow/EasyNetQ/pull/289"}}