diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index 3bb4b7bd6..50a5604a9 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -346,8 +346,8 @@ namespace Discord private Channel AddPrivateChannel(ulong id, ulong recipientId) { Channel channel; - if (_privateChannels.TryGetOrAdd(recipientId, x => new Channel(this, id, new User(this, x, null)), out channel)) - AddChannel(channel); + if (_channels.TryGetOrAdd(id, x => new Channel(this, x, new User(this, recipientId, null)), out channel)) + _privateChannels[recipientId] = channel; return channel; } internal Channel GetPrivateChannel(ulong recipientId) diff --git a/src/Discord.Net/Extensions.cs b/src/Discord.Net/Extensions.cs index 4f4850312..0c75f361d 100644 --- a/src/Discord.Net/Extensions.cs +++ b/src/Discord.Net/Extensions.cs @@ -48,7 +48,21 @@ namespace Discord } } } - + public static bool TryGetOrAdd(this ConcurrentDictionary d, + TKey key, TValue value, out TValue result) + { + while (true) + { + if (d.TryGetValue(key, out result)) + return false; + if (d.TryAdd(key, value)) + { + result = value; + return true; + } + } + } + public static IEnumerable Find(this IEnumerable channels, string name, ChannelType type = null, bool exactMatch = false) { //Search by name diff --git a/src/Discord.Net/Models/Server.cs b/src/Discord.Net/Models/Server.cs index 3c1ae6808..11f256954 100644 --- a/src/Discord.Net/Models/Server.cs +++ b/src/Discord.Net/Models/Server.cs @@ -205,8 +205,8 @@ namespace Discord internal Channel AddChannel(ulong id) { var channel = new Channel(Client, id, this); - channel = _channels.GetOrAdd(id, x => channel); Client.AddChannel(channel); + channel = _channels.GetOrAdd(id, x => channel); return channel; } internal Channel RemoveChannel(ulong id) @@ -389,18 +389,19 @@ namespace Discord #region Users internal User AddUser(ulong id) { - Member user; - if (_users.TryGetOrAdd(id, x => new Member(new User(Client, x, this)), out user)) + Member member = new Member(new User(Client, id, this)); + if (id == Client.CurrentUser.Id) + { + member.User.CurrentGame = Client.CurrentGame; + member.User.Status = Client.Status; + } + + if (_users.TryGetOrAdd(id, member, out member)) { foreach (var channel in AllChannels) - channel.AddUser(user.User); - if (id == Client.CurrentUser.Id) - { - user.User.CurrentGame = Client.CurrentGame; - user.User.Status = Client.Status; - } + channel.AddUser(member.User); } - return user.User; + return member.User; } internal User RemoveUser(ulong id) {