diff --git a/src/MongoDB.Driver/Core/Connections/TcpStreamFactory.cs b/src/MongoDB.Driver/Core/Connections/TcpStreamFactory.cs index be13ca03d17..199b14ca689 100644 --- a/src/MongoDB.Driver/Core/Connections/TcpStreamFactory.cs +++ b/src/MongoDB.Driver/Core/Connections/TcpStreamFactory.cs @@ -203,31 +203,40 @@ private void Connect(Socket socket, EndPoint endPoint, CancellationToken cancell private async Task ConnectAsync(Socket socket, EndPoint endPoint, CancellationToken cancellationToken) { - var timeoutTask = Task.Delay(_settings.ConnectTimeout, cancellationToken); - var connectTask = socket.ConnectAsync(endPoint); + Task connectTask; - await Task.WhenAny(connectTask, timeoutTask).ConfigureAwait(false); - - if (!connectTask.IsCompleted) +#if !NET472 + connectTask = socket.ConnectAsync(endPoint); +#else + var dnsEndPoint = endPoint as DnsEndPoint; + if (dnsEndPoint != null) { - try - { - socket.Dispose(); - // should await on the read task to avoid UnobservedTaskException - await connectTask.ConfigureAwait(false); - } catch { } - - cancellationToken.ThrowIfCancellationRequested(); - throw new TimeoutException($"Timed out connecting to {endPoint}. Timeout was {_settings.ConnectTimeout}."); + // mono doesn't support DnsEndPoint in its BeginConnect method. + connectTask = Task.Factory.FromAsync(socket.BeginConnect(dnsEndPoint.Host, dnsEndPoint.Port, null, null), socket.EndConnect); } - + else + { + connectTask = Task.Factory.FromAsync(socket.BeginConnect(endPoint, null, null), socket.EndConnect); + } +#endif try { - await connectTask.ConfigureAwait(false); + await connectTask.WaitAsync(_settings.ConnectTimeout, cancellationToken).ConfigureAwait(false); } - catch + catch (Exception ex) { - try { socket.Dispose(); } catch { } + try + { + socket.Dispose(); + connectTask.IgnoreExceptions(); + } + catch { } + + if (ex is TimeoutException) + { + throw new TimeoutException($"Timed out connecting to {endPoint}. Timeout was {_settings.ConnectTimeout}."); + } + throw; } }