/// <summary> /// Launches the worker threads and waits for them to complete. /// </summary> /// <param name="data">The threading data.</param> /// <param name="count">The number of threads to create.</param> /// <returns>Returns a value indicating whether analysis of all /// files has been completed. If this returns false, another round /// of analysis must be performed.</returns> private bool RunWorkerThreads(StyleCopThread.Data data, int count) { Param.AssertNotNull(data, "data"); Param.AssertGreaterThanZero(count, "count"); StyleCopTrace.In(data, count); // Indicates whether total analysis of all files has been completed. bool complete = true; // Create the thread class arrays. //// StyleCopThread[] threadClasses = new StyleCopThread[count]; StyleCopThread thread = new StyleCopThread(data); thread.DoWork(null); //// countdown = new Countdown(count); //// Allocate and start all the threads. //// for (int i = 0; i < count; ++i) //// { //// Allocate the worker classes for this thread. //// threadClasses[i] = new StyleCopThread(data); //// Register for the completion event on the thread data class. We do not use the standard BackgroundWorker //// completion event because for some reason it does not get fired when running inside of Visual Studio using //// the MSBuild task, and so everything ends up blocked. This may have to do with the way Visual Studio uses //// threads when running a build. Therefore, we do not rely on the BackgroundWorker's completion event, and //// instead use our own event. //// threadClasses[i].ThreadCompleted += this.StyleCopThreadCompleted; //// new Thread(threadClasses[i].DoWork).Start(); ////} // Blocks until Signal has been called 'n' times //// countdown.Wait(); complete = thread.Complete; //// Dispose the workers and determine whether all analysis is complete. ////for (int i = 0; i < count; ++i) ////{ //// if (!threadClasses[i].Complete) //// { //// complete = false; //// } ////} return StyleCopTrace.Out(complete); }
/// <summary> /// Initializes a new instance of the StyleCopThreadCompletedEventArgs class. /// </summary> /// <param name="data">The thread data.</param> public StyleCopThreadCompletedEventArgs(StyleCopThread.Data data) { Param.AssertNotNull(data, "data"); this.data = data; }
/// <summary> /// Initializes the project to prepare it for analysis. /// </summary> /// <param name="project">The project to initialize.</param> /// <param name="data">The analysis data object.</param> /// <param name="cache">The file cache.</param> private static void InitializeProjectForAnalysis(CodeProject project, StyleCopThread.Data data, ResultsCache cache) { Param.AssertNotNull(project, "project"); Param.AssertNotNull(data, "data"); Param.Ignore(cache); // Get the status object for the project. ProjectStatus projectStatus = data.GetProjectStatus(project); Debug.Assert(projectStatus != null, "There is no status for the given project."); // Load the settings for the project. If the project already contains settings, use those. // Otherwise, load them from scratch. if (!project.SettingsLoaded) { project.Settings = data.GetSettings(project); project.SettingsLoaded = true; } StyleCopCore.CheckForStyleCopUpdate(project); // Load the project configuration from the cache and compare it to the // current project configuration. string configuration = cache == null ? null : cache.LoadProject(project); if (configuration == null) { projectStatus.IgnoreResultsCache = true; } else { projectStatus.IgnoreResultsCache = !StyleCopCore.CompareCachedConfiguration( project.Configuration, configuration); } if (cache != null && project.WriteCache) { cache.SaveProject(project); } }
/// <summary> /// Launches the worker threads and waits for them to complete. /// </summary> /// <param name="data">The threading data.</param> /// <param name="count">The number of threads to create.</param> /// <returns>Returns a value indicating whether analysis of all /// files has been completed. If this returns false, another round /// of analysis must be performed.</returns> private bool RunWorkerThreads(StyleCopThread.Data data, int count) { Param.AssertNotNull(data, "data"); Param.AssertGreaterThanZero(count, "count"); // Indicates whether total sanalysis of all files has been completed. bool complete = true; // Create the worker and thread class arrays. BackgroundWorker[] workers = new BackgroundWorker[count]; StyleCopThread[] threadClasses = new StyleCopThread[count]; // Allocate and start all the threads. for (int i = 0; i < count; ++i) { // Allocate the worker classes for this thread. workers[i] = new BackgroundWorker(); threadClasses[i] = new StyleCopThread(data); // Register for events on the background worker class. workers[i].DoWork += new DoWorkEventHandler(threadClasses[i].DoWork); // Register for the completion event on the thread data class. We do not use the standard BackgroundWorker // completion event because for some reason it does not get fired when running inside of Visual Studio using // the MSBuild task, and so everything ends up blocked. This may have to do with the way Visual Studio uses // threads when running a build. Therefore, we do not rely on the BackgroundWorker's completion event, and // instead use our own event. threadClasses[i].ThreadCompleted += new EventHandler<StyleCopThreadCompletedEventArgs>(this.StyleCopThreadCompleted); // Indicate that we are launching another thread. data.IncrementThreadCount(); } // The lock is required so that we can wait on the Monitor. lock (this) { // Start each of the worker threads. for (int i = 0; i < count; ++i) { workers[i].RunWorkerAsync(); } // Wait for the threads to complete. Monitor.Wait(this); } // Dispose the workers and determine whether all analysis is complete. for (int i = 0; i < count; ++i) { workers[i].Dispose(); if (!threadClasses[i].Complete) { complete = false; } } return complete; }