/// <summary> /// Gets the position asynchronous. /// </summary> /// <param name="timeout">The timeout.</param> /// <param name="cancelToken">The cancel token.</param> /// <param name="includeHeading">if set to <c>true</c> [include heading].</param> /// <returns>Task<Position>.</returns> /// <exception cref="ArgumentOutOfRangeException">timeout;Timeout must be positive or Timeout.Infinite</exception> public Task<Position> GetPositionAsync(int timeout, CancellationToken cancelToken, bool includeHeading) { if (timeout <= 0 && timeout != Timeout.Infinite) { throw new ArgumentOutOfRangeException("timeout", "Timeout must be positive or Timeout.Infinite"); } TaskCompletionSource<Position> tcs; if (!IsListening) { var m = GetManager(); tcs = new TaskCompletionSource<Position>(m); var singleListener = new GeolocationSingleUpdateDelegate(m, DesiredAccuracy, includeHeading, timeout, cancelToken); m.Delegate = singleListener; m.StartUpdatingLocation(); if (includeHeading && SupportsHeading) { m.StartUpdatingHeading(); } return singleListener.Task; } tcs = new TaskCompletionSource<Position>(); if (_position == null) { EventHandler<PositionErrorEventArgs> gotError = null; gotError = (s, e) => { tcs.TrySetException(new GeolocationException(e.Error)); PositionError -= gotError; }; PositionError += gotError; EventHandler<PositionEventArgs> gotPosition = null; gotPosition = (s, e) => { tcs.TrySetResult(e.Position); PositionChanged -= gotPosition; }; PositionChanged += gotPosition; } else { tcs.SetResult(_position); } return tcs.Task; }