Fixed some race conditions

This commit is contained in:
RogueException
2015-12-26 02:47:15 -04:00
parent 75d2d456a5
commit 8cc94994d6
3 changed files with 28 additions and 13 deletions

View File

@@ -346,8 +346,8 @@ namespace Discord
private Channel AddPrivateChannel(ulong id, ulong recipientId) private Channel AddPrivateChannel(ulong id, ulong recipientId)
{ {
Channel channel; Channel channel;
if (_privateChannels.TryGetOrAdd(recipientId, x => new Channel(this, id, new User(this, x, null)), out channel)) if (_channels.TryGetOrAdd(id, x => new Channel(this, x, new User(this, recipientId, null)), out channel))
AddChannel(channel); _privateChannels[recipientId] = channel;
return channel; return channel;
} }
internal Channel GetPrivateChannel(ulong recipientId) internal Channel GetPrivateChannel(ulong recipientId)

View File

@@ -48,7 +48,21 @@ namespace Discord
} }
} }
} }
public static bool TryGetOrAdd<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> 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<Channel> Find(this IEnumerable<Channel> channels, string name, ChannelType type = null, bool exactMatch = false) public static IEnumerable<Channel> Find(this IEnumerable<Channel> channels, string name, ChannelType type = null, bool exactMatch = false)
{ {
//Search by name //Search by name

View File

@@ -205,8 +205,8 @@ namespace Discord
internal Channel AddChannel(ulong id) internal Channel AddChannel(ulong id)
{ {
var channel = new Channel(Client, id, this); var channel = new Channel(Client, id, this);
channel = _channels.GetOrAdd(id, x => channel);
Client.AddChannel(channel); Client.AddChannel(channel);
channel = _channels.GetOrAdd(id, x => channel);
return channel; return channel;
} }
internal Channel RemoveChannel(ulong id) internal Channel RemoveChannel(ulong id)
@@ -389,18 +389,19 @@ namespace Discord
#region Users #region Users
internal User AddUser(ulong id) internal User AddUser(ulong id)
{ {
Member user; Member member = new Member(new User(Client, id, this));
if (_users.TryGetOrAdd(id, x => new Member(new User(Client, x, this)), out user)) 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) foreach (var channel in AllChannels)
channel.AddUser(user.User); channel.AddUser(member.User);
if (id == Client.CurrentUser.Id)
{
user.User.CurrentGame = Client.CurrentGame;
user.User.Status = Client.Status;
}
} }
return user.User; return member.User;
} }
internal User RemoveUser(ulong id) internal User RemoveUser(ulong id)
{ {