RecursiveDirectoryInfoQuery AcquireLockForQuery(FilePath path, bool getRemoteStatus) { RecursiveDirectoryInfoQuery rq; bool query = false; lock (queryLock) { rq = recursiveDirectoryQueryQueue.FirstOrDefault(q => q.Directory == path); if (rq == null) { query = true; var mre = new ManualResetEvent(false); rq = new RecursiveDirectoryInfoQuery { Directory = path, GetRemoteStatus = getRemoteStatus, ResetEvent = mre, Count = 1, }; } else { Interlocked.Increment(ref rq.Count); } } if (query) { AddQuery(rq); } return(rq); }
public VersionInfo[] GetDirectoryVersionInfo(FilePath localDirectory, bool getRemoteStatus, bool recursive) { try { if (recursive) { using (var mre = new ManualResetEvent(false)) { var rq = new RecursiveDirectoryInfoQuery { Directory = localDirectory, GetRemoteStatus = getRemoteStatus, ResetEvent = mre, }; AddQuery(rq); rq.ResetEvent.WaitOne(); return(rq.Result); } } var status = infoCache.GetDirectoryStatus(localDirectory); if (status != null && !status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus)) { return(status.FileInfo); } // If there is no cached status, query it asynchronously DirectoryInfoQuery q = new DirectoryInfoQuery() { Directory = localDirectory, GetRemoteStatus = getRemoteStatus }; AddQuery(q); // If we have a status value but the value was invalidated (RequiresRefresh == true) // then we return the invalidated value while we start an async query to get the new one if (status != null && status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus)) { return(status.FileInfo); } return(new VersionInfo[0]); } finally { //Console.WriteLine ("GetDirectoryVersionInfo " + localDirectory + " - " + (DateTime.Now - now).TotalMilliseconds); } }
public VersionInfo[] GetDirectoryVersionInfo(FilePath localDirectory, bool getRemoteStatus, bool recursive) { try { if (recursive) { RecursiveDirectoryInfoQuery rq = AcquireLockForQuery(localDirectory, getRemoteStatus); rq.ResetEvent.WaitOne(); lock (queryLock) if (Interlocked.Decrement(ref rq.Count) == 0) { rq.ResetEvent.Dispose(); } return(rq.Result); } var status = infoCache.GetDirectoryStatus(localDirectory); if (status != null && !status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus)) { return(status.FileInfo); } // If there is no cached status, query it asynchronously DirectoryInfoQuery q = new DirectoryInfoQuery() { Directory = localDirectory, GetRemoteStatus = getRemoteStatus }; AddQuery(q); // If we have a status value but the value was invalidated (RequiresRefresh == true) // then we return the invalidated value while we start an async query to get the new one if (status != null && status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus)) { return(status.FileInfo); } return(new VersionInfo[0]); } finally { //Console.WriteLine ("GetDirectoryVersionInfo " + localDirectory + " - " + (DateTime.Now - now).TotalMilliseconds); } }
void RunQueries (object ob) { // DateTime t = DateTime.Now; // Console.WriteLine ("RunQueries started"); VersionInfoQuery [] fileQueryQueueClone; DirectoryInfoQuery [] directoryQueryQueueClone; RecursiveDirectoryInfoQuery [] recursiveDirectoryQueryQueueClone = new RecursiveDirectoryInfoQuery[0]; try { while (true) { lock (queryLock) { if (fileQueryQueue.Count == 0 && directoryQueryQueue.Count == 0 && recursiveDirectoryQueryQueue.Count == 0) { queryRunning = false; return; } fileQueryQueueClone = fileQueryQueue.ToArray (); fileQueryQueue.Clear (); filesInQueryQueue.Clear (); directoryQueryQueueClone = directoryQueryQueue.ToArray (); directoriesInQueryQueue.Clear (); directoryQueryQueue.Clear (); recursiveDirectoryQueryQueueClone = recursiveDirectoryQueryQueue.ToArray (); recursiveDirectoriesInQueryQueue.Clear (); recursiveDirectoryQueryQueue.Clear (); } // Ensure we do not execute this with the query lock held, otherwise the IDE can hang while trying to add // new queries to the queue while long-running VCS operations are being performed var groups = fileQueryQueueClone.GroupBy (q => (q.QueryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0); foreach (var group in groups) { var status = OnGetVersionInfo (group.SelectMany (q => q.Paths), group.Key); infoCache.SetStatus (status); } foreach (var item in directoryQueryQueueClone) { var status = OnGetDirectoryVersionInfo (item.Directory, item.GetRemoteStatus, false); infoCache.SetDirectoryStatus (item.Directory, status, item.GetRemoteStatus); } foreach (var item in recursiveDirectoryQueryQueueClone) { try { item.Result = OnGetDirectoryVersionInfo (item.Directory, item.GetRemoteStatus, true); } finally { item.ResetEvent.Set (); } } } } catch (Exception ex) { LoggingService.LogError ("Version control status query failed", ex); //Release all items in current batch foreach (var item in recursiveDirectoryQueryQueueClone) item.ResetEvent.Set (); lock (queryLock) { queryRunning = false; fileQueryQueue.Clear (); filesInQueryQueue.Clear (); directoriesInQueryQueue.Clear (); directoryQueryQueue.Clear (); recursiveDirectoryQueryQueueClone = recursiveDirectoryQueryQueue.ToArray (); recursiveDirectoriesInQueryQueue.Clear (); recursiveDirectoryQueryQueue.Clear (); } //Release newly pending foreach (var item in recursiveDirectoryQueryQueueClone) item.ResetEvent.Set (); } //Console.WriteLine ("RunQueries finished - " + (DateTime.Now - t).TotalMilliseconds); }
RecursiveDirectoryInfoQuery AcquireLockForQuery (FilePath path, bool getRemoteStatus) { RecursiveDirectoryInfoQuery rq; bool query = false; lock (queryLock) { rq = recursiveDirectoryQueryQueue.FirstOrDefault (q => q.Directory == path); if (rq == null) { query = true; var mre = new ManualResetEvent (false); rq = new RecursiveDirectoryInfoQuery { Directory = path, GetRemoteStatus = getRemoteStatus, ResetEvent = mre, Count = 1, }; } else Interlocked.Increment (ref rq.Count); } if (query) AddQuery (rq); return rq; }
void RunQueries(object ob) { // DateTime t = DateTime.Now; // Console.WriteLine ("RunQueries started"); VersionInfoQuery [] fileQueryQueueClone; DirectoryInfoQuery [] directoryQueryQueueClone; RecursiveDirectoryInfoQuery [] recursiveDirectoryQueryQueueClone = new RecursiveDirectoryInfoQuery[0]; try { while (true) { lock (queryLock) { if (fileQueryQueue.Count == 0 && directoryQueryQueue.Count == 0 && recursiveDirectoryQueryQueue.Count == 0) { queryRunning = false; return; } fileQueryQueueClone = fileQueryQueue.ToArray(); fileQueryQueue.Clear(); filesInQueryQueue.Clear(); directoryQueryQueueClone = directoryQueryQueue.ToArray(); directoriesInQueryQueue.Clear(); directoryQueryQueue.Clear(); recursiveDirectoryQueryQueueClone = recursiveDirectoryQueryQueue.ToArray(); recursiveDirectoriesInQueryQueue.Clear(); recursiveDirectoryQueryQueue.Clear(); } // Ensure we do not execute this with the query lock held, otherwise the IDE can hang while trying to add // new queries to the queue while long-running VCS operations are being performed var groups = fileQueryQueueClone.GroupBy(q => (q.QueryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0); foreach (var group in groups) { if (Disposed) { break; } var status = OnGetVersionInfo(group.SelectMany(q => q.Paths), group.Key); infoCache.SetStatus(status); } foreach (var item in directoryQueryQueueClone) { if (Disposed) { break; } var status = OnGetDirectoryVersionInfo(item.Directory, item.GetRemoteStatus, false); infoCache.SetDirectoryStatus(item.Directory, status, item.GetRemoteStatus); } foreach (var item in recursiveDirectoryQueryQueueClone) { try { if (Disposed) { continue; } item.Result = OnGetDirectoryVersionInfo(item.Directory, item.GetRemoteStatus, true); } finally { item.ResetEvent.Set(); } } } } catch (Exception ex) { LoggingService.LogError("Version control status query failed", ex); //Release all items in current batch foreach (var item in recursiveDirectoryQueryQueueClone) { item.ResetEvent.Set(); } lock (queryLock) { queryRunning = false; fileQueryQueue.Clear(); filesInQueryQueue.Clear(); directoriesInQueryQueue.Clear(); directoryQueryQueue.Clear(); recursiveDirectoryQueryQueueClone = recursiveDirectoryQueryQueue.ToArray(); recursiveDirectoriesInQueryQueue.Clear(); recursiveDirectoryQueryQueue.Clear(); } //Release newly pending foreach (var item in recursiveDirectoryQueryQueueClone) { item.ResetEvent.Set(); } } //Console.WriteLine ("RunQueries finished - " + (DateTime.Now - t).TotalMilliseconds); }
public VersionInfo[] GetDirectoryVersionInfo (FilePath localDirectory, bool getRemoteStatus, bool recursive) { try { if (recursive) { using (var mre = new ManualResetEvent (false)) { var rq = new RecursiveDirectoryInfoQuery { Directory = localDirectory, GetRemoteStatus = getRemoteStatus, ResetEvent = mre, }; AddQuery (rq); rq.ResetEvent.WaitOne (); return rq.Result; } } var status = infoCache.GetDirectoryStatus (localDirectory); if (status != null && !status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus)) return status.FileInfo; // If there is no cached status, query it asynchronously DirectoryInfoQuery q = new DirectoryInfoQuery () { Directory = localDirectory, GetRemoteStatus = getRemoteStatus }; AddQuery (q); // If we have a status value but the value was invalidated (RequiresRefresh == true) // then we return the invalidated value while we start an async query to get the new one if (status != null && status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus)) return status.FileInfo; return new VersionInfo[0]; } finally { //Console.WriteLine ("GetDirectoryVersionInfo " + localDirectory + " - " + (DateTime.Now - now).TotalMilliseconds); } }