public bool TryGetVersionInfo(IEnumerable <FilePath> paths, VersionInfoQueryFlags queryFlags, out IReadOnlyList <VersionInfo> infos) { var result = new List <VersionInfo> (); var pathsToQuery = new List <FilePath> (); bool getVersionInfoFailed = false; foreach (var path in paths) { var vi = infoCache.GetStatus(path); if (vi != null) { result.Add(vi); // This status has been invalidated, query it asynchronously if (vi.RequiresRefresh) { pathsToQuery.Add(path); } } else { pathsToQuery.Add(path); getVersionInfoFailed = true; } } if (pathsToQuery.Count > 0) { ExclusiveOperationFactory.StartNew(async delegate { // we don't care about initialization and setstatus async to happen on the exclusive thread, as we're not running a query here. var status = await OnGetVersionInfoAsync(paths, (queryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0).ConfigureAwait(false); foreach (var vi in status) { if (!vi.IsInitialized) { await vi.InitAsync(this).ConfigureAwait(false); } } await infoCache.SetStatusAsync(status).ConfigureAwait(false); }).Ignore(); } if (getVersionInfoFailed) { infos = null; return(false); } infos = result; return(true); }
/// <summary> /// Returns the versioning status of a set of files or directories /// </summary> /// <param name='paths'> /// A list of files or directories /// </param> /// <param name='queryFlags'> /// Use VersionInfoQueryFlags enum for options. /// </param> public async Task <IReadOnlyList <VersionInfo> > GetVersionInfoAsync(IEnumerable <FilePath> paths, VersionInfoQueryFlags queryFlags = VersionInfoQueryFlags.None, CancellationToken cancellationToken = default) { if ((queryFlags & VersionInfoQueryFlags.IgnoreCache) != 0) { var task = await ExclusiveOperationFactory.StartNew(delegate { // We shouldn't use IEnumerable because elements don't save property modifications. return(OnGetVersionInfoAsync(paths, (queryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0, cancellationToken)); }).ConfigureAwait(false); var res = await task.ConfigureAwait(false); foreach (var vi in res) { if (!vi.IsInitialized) { await vi.InitAsync(this, cancellationToken).ConfigureAwait(false); } } await infoCache.SetStatusAsync(res, cancellationToken : cancellationToken).ConfigureAwait(false); return(res); } var pathsToQuery = new List <FilePath> (); var result = new List <VersionInfo> (); foreach (var path in paths) { var vi = infoCache.GetStatus(path); if (vi != null) { result.Add(vi); // This status has been invalidated, query it asynchronously if (vi.RequiresRefresh) { pathsToQuery.Add(path); } } else { // If there is no cached status, query it asynchronously vi = new VersionInfo(path, "", Directory.Exists(path), VersionStatus.Versioned, null, VersionStatus.Versioned, null); await infoCache.SetStatusAsync(vi, false).ConfigureAwait(false); result.Add(vi); pathsToQuery.Add(path); } // Console.WriteLine ("GetVersionInfo " + string.Join (", ", paths.Select (p => p.FullPath))); } if (pathsToQuery.Count > 0) { ExclusiveOperationFactory.StartNew(async delegate { var status = await OnGetVersionInfoAsync(pathsToQuery, (queryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0, cancellationToken).ConfigureAwait(false); foreach (var vi in status) { if (!vi.IsInitialized) { await vi.InitAsync(this, cancellationToken).ConfigureAwait(false); } } await infoCache.SetStatusAsync(status, cancellationToken).ConfigureAwait(false); }).Ignore(); } return(result); }