public async Task ConnectAsync(string host, string applicationName, string userName, string password, CancellationToken cancellationToken) { if (client != null) { throw new InvalidOperationException(); } log.Debug(l => l(LogMessages.Connecting, userName, host)); connected = new TaskCompletionSource <bool>(); disconnected = new TaskCompletionSource <bool>(); client = SDK.CreateSDK(applicationName); Device = client.CreateMTA(); Device.NotifyConnectHandlers = NotifyConnectHandler; Device.NotifyConnectionStateHandlers = NotifyConnectionStateHandler; Device.Connect(host, userName, password); disconnectedTokenSource = new CancellationTokenSource(); var disconnectedToken = disconnectedTokenSource.Token; processMessagesTask = Task.Run(() => ProcessMessages(disconnectedToken), cancellationToken); try { await connected.Task; } catch (Exception e) { log.Error(l => l(LogMessages.ConnectFailed), e); disconnected.TrySetResult(true); DisconnectAsync(); throw; } }