@@ -9,7 +9,7 @@ namespace Discord.Collections | |||||
public abstract class AsyncCollection<TValue> : IEnumerable<TValue> | public abstract class AsyncCollection<TValue> : IEnumerable<TValue> | ||||
where TValue : class | where TValue : class | ||||
{ | { | ||||
private static readonly object _writerLock = new object(); | |||||
private readonly object _writerLock; | |||||
internal class CollectionItemEventArgs : EventArgs | internal class CollectionItemEventArgs : EventArgs | ||||
{ | { | ||||
@@ -53,9 +53,10 @@ namespace Discord.Collections | |||||
protected readonly DiscordClient _client; | protected readonly DiscordClient _client; | ||||
protected readonly ConcurrentDictionary<string, TValue> _dictionary; | protected readonly ConcurrentDictionary<string, TValue> _dictionary; | ||||
protected AsyncCollection(DiscordClient client) | |||||
protected AsyncCollection(DiscordClient client, object writerLock) | |||||
{ | { | ||||
_client = client; | _client = client; | ||||
_writerLock = writerLock; | |||||
_dictionary = new ConcurrentDictionary<string, TValue>(); | _dictionary = new ConcurrentDictionary<string, TValue>(); | ||||
} | } | ||||
@@ -6,8 +6,8 @@ namespace Discord.Collections | |||||
{ | { | ||||
public sealed class Channels : AsyncCollection<Channel> | public sealed class Channels : AsyncCollection<Channel> | ||||
{ | { | ||||
internal Channels(DiscordClient client) | |||||
: base(client) { } | |||||
internal Channels(DiscordClient client, object writerLock) | |||||
: base(client, writerLock) { } | |||||
internal Channel GetOrAdd(string id, string serverId, string recipientId = null) => GetOrAdd(id, () => new Channel(_client, id, serverId, recipientId)); | internal Channel GetOrAdd(string id, string serverId, string recipientId = null) => GetOrAdd(id, () => new Channel(_client, id, serverId, recipientId)); | ||||
internal new Channel TryRemove(string id) => base.TryRemove(id); | internal new Channel TryRemove(string id) => base.TryRemove(id); | ||||
@@ -6,8 +6,8 @@ namespace Discord.Collections | |||||
{ | { | ||||
public sealed class Members : AsyncCollection<Member> | public sealed class Members : AsyncCollection<Member> | ||||
{ | { | ||||
internal Members(DiscordClient client) | |||||
: base(client) { } | |||||
internal Members(DiscordClient client, object writerLock) | |||||
: base(client, writerLock) { } | |||||
private string GetKey(string userId, string serverId) => serverId + '_' + userId; | private string GetKey(string userId, string serverId) => serverId + '_' + userId; | ||||
@@ -5,8 +5,8 @@ namespace Discord.Collections | |||||
public sealed class Messages : AsyncCollection<Message> | public sealed class Messages : AsyncCollection<Message> | ||||
{ | { | ||||
private readonly MessageCleaner _msgCleaner; | private readonly MessageCleaner _msgCleaner; | ||||
internal Messages(DiscordClient client) | |||||
: base(client) | |||||
internal Messages(DiscordClient client, object writerLock) | |||||
: base(client, writerLock) | |||||
{ | { | ||||
_msgCleaner = new MessageCleaner(client); | _msgCleaner = new MessageCleaner(client); | ||||
} | } | ||||
@@ -6,8 +6,8 @@ namespace Discord.Collections | |||||
{ | { | ||||
public sealed class Roles : AsyncCollection<Role> | public sealed class Roles : AsyncCollection<Role> | ||||
{ | { | ||||
internal Roles(DiscordClient client) | |||||
: base(client) { } | |||||
internal Roles(DiscordClient client, object writerLock) | |||||
: base(client, writerLock) { } | |||||
internal Role GetOrAdd(string id, string serverId) => GetOrAdd(id, () => new Role(_client, id, serverId)); | internal Role GetOrAdd(string id, string serverId) => GetOrAdd(id, () => new Role(_client, id, serverId)); | ||||
internal new Role TryRemove(string id) => base.TryRemove(id); | internal new Role TryRemove(string id) => base.TryRemove(id); | ||||
@@ -6,8 +6,8 @@ namespace Discord.Collections | |||||
{ | { | ||||
public sealed class Servers : AsyncCollection<Server> | public sealed class Servers : AsyncCollection<Server> | ||||
{ | { | ||||
internal Servers(DiscordClient client) | |||||
: base(client) { } | |||||
internal Servers(DiscordClient client, object writerLock) | |||||
: base(client, writerLock) { } | |||||
internal Server GetOrAdd(string id) => base.GetOrAdd(id, () => new Server(_client, id)); | internal Server GetOrAdd(string id) => base.GetOrAdd(id, () => new Server(_client, id)); | ||||
internal new Server TryRemove(string id) => base.TryRemove(id); | internal new Server TryRemove(string id) => base.TryRemove(id); | ||||
@@ -6,8 +6,8 @@ namespace Discord.Collections | |||||
{ | { | ||||
public sealed class Users : AsyncCollection<User> | public sealed class Users : AsyncCollection<User> | ||||
{ | { | ||||
internal Users(DiscordClient client) | |||||
: base(client) { } | |||||
internal Users(DiscordClient client, object writerLock) | |||||
: base(client, writerLock) { } | |||||
internal User GetOrAdd(string id) => GetOrAdd(id, () => new User(_client, id)); | internal User GetOrAdd(string id) => GetOrAdd(id, () => new User(_client, id)); | ||||
internal new User TryRemove(string id) => base.TryRemove(id); | internal new User TryRemove(string id) => base.TryRemove(id); | ||||
@@ -136,12 +136,13 @@ namespace Discord | |||||
}; | }; | ||||
} | } | ||||
_channels = new Channels(this); | |||||
_members = new Members(this); | |||||
_messages = new Messages(this); | |||||
_roles = new Roles(this); | |||||
_servers = new Servers(this); | |||||
_users = new Users(this); | |||||
object cacheLock = new object(); | |||||
_channels = new Channels(this, cacheLock); | |||||
_members = new Members(this, cacheLock); | |||||
_messages = new Messages(this, cacheLock); | |||||
_roles = new Roles(this, cacheLock); | |||||
_servers = new Servers(this, cacheLock); | |||||
_users = new Users(this, cacheLock); | |||||
_dataSocket.LogMessage += (s, e) => RaiseOnLog(e.Severity, LogMessageSource.DataWebSocket, e.Message); | _dataSocket.LogMessage += (s, e) => RaiseOnLog(e.Severity, LogMessageSource.DataWebSocket, e.Message); | ||||
if (_config.EnableVoice) | if (_config.EnableVoice) | ||||
@@ -645,9 +646,6 @@ namespace Discord | |||||
string token; | string token; | ||||
try | try | ||||
{ | { | ||||
var cancelToken = new CancellationTokenSource(); | |||||
cancelToken.CancelAfter(5000); | |||||
_api.CancelToken = cancelToken.Token; | |||||
var response = await _api.Login(email, password).ConfigureAwait(false); | var response = await _api.Login(email, password).ConfigureAwait(false); | ||||
token = response.Token; | token = response.Token; | ||||
if (_config.LogLevel >= LogMessageSeverity.Verbose) | if (_config.LogLevel >= LogMessageSeverity.Verbose) | ||||