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; } else { tcs = new TaskCompletionSource<Position>(); if (this.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(this.position); } return tcs.Task; }