コード例 #1
0
		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;
		}
コード例 #2
0
		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);
		}
コード例 #3
0
		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);
			}
		}