/// <summary> /// Cleans up the instance of ResourceStaticAnalysis. Used to flush all referenced objects to make sure memory doesn't grow indefinitely. /// </summary> public override void Cleanup() { StringCache.Clear(); StringCache.Resize(0); if (EngineCleanup != null) { Trace.TraceInformation("Firing EngineCleanup event."); EngineCleanup(this, new EventArgs()); } else { Trace.TraceWarning("No listeners of EngineCleanup event. Event not fired."); } }
/// <summary> /// This is the second thread of ResourceStaticAnalysis. It communicates with /// Classification Object and Space factories in order to load objects from /// data packages. /// It also does all the required pre-processing on objects, such as marking objects /// for processing. /// It then starts Enigne3rdThread in order to start Classification Object processing by rules /// </summary> /// <exception cref="ResourceStaticAnalysisEngineInitializationException">Thrown when: /// <para/>expected data source provider is not available /// <para/>or where there is no primary data source /// <para/>or when data source instance could not be initialized properly. This could happen - for example - if a file comprising the datasource does not exist. /// <para/>Inner exception is of type <see cref="ResourceStaticAnalysisException"/> and contains more details about the specific cause of failure. /// </exception> private void LoadAndQueueCOs() { Trace.TraceInformation("Loading and queueing objects started."); if (LoadingStarting != null) { LoadingStarting(this, null); } /* this loads all CO objects of type specified in dsPkg and from data sources * specified in dsPkg into an appropriate space supporting that type of CO. * if the space does not already exist in coSpaces it will be created. * otherwise COs will be added to the existing space. * * Consider re-designing this part to be multi-thread so packages * are loaded in separate threads to speed up */ _coLoaded = 0; if (_dataSourcePackages != null && _dataSourcePackages.Count > 0) { Trace.TraceInformation("Engine is processing packages..."); while (_dataSourcePackages.Count > 0) { DataSourcePackage dataSourcePackage; lock ((_dataSourcePackages as ICollection).SyncRoot) { dataSourcePackage = _dataSourcePackages.Dequeue(); } if (dataSourcePackage != null) { try { Trace.TraceInformation("Engine is processing package: {0}", dataSourcePackage.ToString()); dataSourcePackage.Initialize(this._dataSourceProviders); var loadedObjects = LoadClassificationObjects(dataSourcePackage, this.CurrentRuleManager.RuleCount); if (loadedObjects.Count < 1) { continue; } PrepareResourceItems(loadedObjects); } catch (Exception e) { throw new ResourceStaticAnalysisEngineInitializationException(String.Format(CultureInfo.CurrentCulture, "Error processing DataSourcePackage: {0}.", dataSourcePackage.ToString()), e); } } } } else if (_usePreLoadedCOs) { Trace.TraceInformation("Engine is processing objects..."); List <ClassificationObject> loadedObjects = ParsedCOList; if (loadedObjects != null && loadedObjects.Count > 0) { PrepareResourceItems(loadedObjects); } } _preProcessedInput.TrimExcess(); // now that we know the number of objects to process, set the string cache capacity to limit the // number of cache resizes during execution StringCache.Resize(_preProcessedInput.Count * 5); if (_engineConfiguration.DataSourcePkgs != null) { //All DataSourcePackages have been loaded, we can dispose of the packages and underlying //data sources _engineConfiguration.DataSourcePkgs.ForEach(dsp => { if (!Object.ReferenceEquals(dsp, null)) { dsp.Dispose(); } }); } if (LoadingFinished != null) { LoadingFinished(this, new EventArgs <int>(_preProcessedInput.Count)); } Trace.TraceInformation("Loading and queueing objects finished. (took {1}). Objects loaded: {0}.", _coLoaded, Monitor.LoadingElapsed); }