/// <summary> /// Handle a new find request, and manage the lifetime of this additional find request. /// </summary> private async void HandleFindRequest(FindEntry findEntry, CancellationToken cancellationToken) { Debug.Assert(_appContext == SynchronizationContext.Current, "HandleFind must be called on the main Unity app thread."); findEntry.Count++; // If the first find request, kick of internal search for the anchor if (findEntry.Count == 1) { TryWatching(); // Notify listeners of the count change ActiveSearchesCountChanged?.Invoke(this, new AnchoringServiceSearchingArgs(_pendingFinds.Count)); } Task findTask; if (_defaultProfile.SearchTimeout >= 0) { findTask = Task.WhenAny(findEntry.TaskCompletionSource.Task, Task.Delay(TimeSpan.FromSeconds(_defaultProfile.SearchTimeout))); } else { findTask = findEntry.TaskCompletionSource.Task; } try { await findTask.WithCancellation(cancellationToken); LogVerbose("Found anchor. (anchor id: {0})", findEntry.AnchorId); } catch (TaskCanceledException) { LogVerbose("Find was canceled. (anchor id: {0})", findEntry.AnchorId); } catch (Exception) { // ignore other failures. } // If nothing is wanting to find this anchor id, remove it from the searches. if (--findEntry.Count == 0 && _pendingFinds.Remove(findEntry.AnchorId)) { LogVerbose("No more find requests for this anchor. (anchor id: {0})", findEntry.AnchorId); // If search hasn't completed, notify task listeners of the cancelation. findEntry.TaskCompletionSource?.TrySetCanceled(); // In order for this anchor id search to stop, we have to restart all searches. TryWatching(); // Notify listeners of the count change ActiveSearchesCountChanged?.Invoke(this, new AnchoringServiceSearchingArgs(_pendingFinds.Count)); } else { LogVerbose("There are still active find requests for this anchor. (anchor id: {0}) (requests: {1})", findEntry.AnchorId, findEntry.Count); } }
/// <summary> /// Start finding cloud spatial anchor, once found returned task is compelted. /// </summary> public Task <CloudSpatialAnchor> Find(string cloudSpatialAnchorId, CancellationToken cancellationToken) { LogVerbose("Find(string) called. (anchor id: {0})", cloudSpatialAnchorId); FindEntry findEntry; if (!_pendingFinds.TryGetValue(cloudSpatialAnchorId, out findEntry)) { _pendingFinds[cloudSpatialAnchorId] = findEntry = new FindEntry(cloudSpatialAnchorId); } HandleFindRequest(findEntry, cancellationToken); return(findEntry.TaskCompletionSource.Task); }
public static void OnFindEntry(LogEntryEventArgs e) { FindEntry?.Invoke(null, e); }