internal async Task FinishConnectAudio(string url, string token) { //TODO: Mem Leak: Disconnected/Connected handlers arent cleaned up var voiceState = GetVoiceState(Discord.CurrentUser.Id).Value; await _audioLock.WaitAsync().ConfigureAwait(false); try { if (_audioClient != null) { await RepopulateAudioStreamsAsync().ConfigureAwait(false); await _audioClient.StartAsync(url, Discord.CurrentUser.Id, voiceState.VoiceSessionId, token).ConfigureAwait(false); } } catch (OperationCanceledException) { await DisconnectAudioInternalAsync().ConfigureAwait(false); } catch (Exception e) { await _audioConnectPromise.SetExceptionAsync(e).ConfigureAwait(false); await DisconnectAudioInternalAsync().ConfigureAwait(false); } finally { _audioLock.Release(); } }
public static Task RunAsync(CefThreadId threadId, Action action) { if (CefRuntime.CurrentlyOn(threadId)) { action(); return(TaskHelpers.Completed()); } else { var tcs = new TaskCompletionSource <FakeVoid>(); StartNew(threadId, () => { try { action(); tcs.SetResultAsync(default(FakeVoid)); } catch (Exception e) { tcs.SetExceptionAsync(e); } }); return(tcs.Task); } }
internal async Task FinishConnectAudio(int id, string url, string token) { var voiceState = GetVoiceState(Discord.CurrentUser.Id).Value; await _audioLock.WaitAsync().ConfigureAwait(false); try { if (_audioClient == null) { var audioClient = new AudioClient(this, id); var promise = _audioConnectPromise; audioClient.Disconnected += async ex => { //If the initial connection hasn't been made yet, reconnecting will lead to deadlocks if (!promise.Task.IsCompleted) { try { audioClient.Dispose(); } catch { } _audioClient = null; if (ex != null) { await promise.TrySetExceptionAsync(ex); } else { await promise.TrySetCanceledAsync(); } return; } //TODO: Implement reconnect /*await _audioLock.WaitAsync().ConfigureAwait(false); * try * { * if (AudioClient == audioClient) //Only reconnect if we're still assigned as this guild's audio client * { * if (ex != null) * { * //Reconnect if we still have channel info. * //TODO: Is this threadsafe? Could channel data be deleted before we access it? * var voiceState2 = GetVoiceState(Discord.CurrentUser.Id); * if (voiceState2.HasValue) * { * var voiceChannelId = voiceState2.Value.VoiceChannel?.Id; * if (voiceChannelId != null) * { * await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, voiceChannelId, voiceState2.Value.IsSelfDeafened, voiceState2.Value.IsSelfMuted); * return; * } * } * } * try { audioClient.Dispose(); } catch { } * AudioClient = null; * } * } * finally * { * _audioLock.Release(); * }*/ }; _audioClient = audioClient; } await _audioClient.ConnectAsync(url, Discord.CurrentUser.Id, voiceState.VoiceSessionId, token).ConfigureAwait(false); await _audioConnectPromise.TrySetResultAsync(_audioClient).ConfigureAwait(false); } catch (OperationCanceledException) { await DisconnectAudioInternalAsync().ConfigureAwait(false); } catch (Exception e) { await _audioConnectPromise.SetExceptionAsync(e).ConfigureAwait(false); await DisconnectAudioInternalAsync().ConfigureAwait(false); } finally { _audioLock.Release(); } }
public async Task FinishConnectAudio(int id, string url, string token) { var voiceState = GetVoiceState(CurrentUser.Id).Value; await _audioLock.WaitAsync().ConfigureAwait(false); try { if (AudioClient == null) { var audioClient = new AudioClient(this, id); audioClient.Disconnected += async ex => { await _audioLock.WaitAsync().ConfigureAwait(false); try { if (AudioClient == audioClient) //Only reconnect if we're still assigned as this guild's audio client { if (ex != null) { //Reconnect if we still have channel info. //TODO: Is this threadsafe? Could channel data be deleted before we access it? var voiceState2 = GetVoiceState(CurrentUser.Id); if (voiceState2.HasValue) { var voiceChannelId = voiceState2.Value.VoiceChannel?.Id; if (voiceChannelId != null) { await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, voiceChannelId, voiceState2.Value.IsSelfDeafened, voiceState2.Value.IsSelfMuted); } } } else { try { AudioClient.Dispose(); } catch { } AudioClient = null; } } } finally { _audioLock.Release(); } }; AudioClient = audioClient; } await AudioClient.ConnectAsync(url, CurrentUser.Id, voiceState.VoiceSessionId, token).ConfigureAwait(false); await _audioConnectPromise.TrySetResultAsync(AudioClient).ConfigureAwait(false); } catch (OperationCanceledException) { await DisconnectAudioAsync(); } catch (Exception e) { await _audioConnectPromise.SetExceptionAsync(e).ConfigureAwait(false); await DisconnectAudioAsync(); } finally { _audioLock.Release(); } }