BackgroundWorker_DoWork ( object sender, DoWorkEventArgs e ) { Debug.Assert(sender is BackgroundWorker); AssertValid(); BackgroundWorker oBackgroundWorker = (BackgroundWorker)sender; Debug.Assert(e.Argument is CalculateGraphMetricsAsyncArgs); CalculateGraphMetricsAsyncArgs oCalculateGraphMetricsAsyncArgs = (CalculateGraphMetricsAsyncArgs)e.Argument; CalculateGraphMetricsAsyncInternal(oCalculateGraphMetricsAsyncArgs, m_oBackgroundWorker, e); }
/* Create analyzers and graph according to a "setting" object provided by outter View component; then pass to a BackgroundWorker. * In this project, this is invoked by a Dialog onload event handler. * */ public void calculateMetricsAsync(IGraph graph, MetricsCheckedList checkedlist) { if (m_oBackgroundWorker != null && m_oBackgroundWorker.IsBusy) { /* throw new InvalidOperationException(String.Format( "{0}:{1}: An asynchronous operation is already in progress." , this.ClassName, MethodName )); * */ } // logic about which calculator should be created CalculateGraphMetricsAsyncArgs args = new CalculateGraphMetricsAsyncArgs(); // add analyzer to this object and pass to BackgroundWorker args.Analyzers = new LinkedList<AnalyzerBase>(); args.Graph = graph; if (checkedlist.overall_graph_metrics == true) {args.Analyzers.AddLast(new OverallMetricCalculator()); } if (checkedlist.vertex_degree == true) {args.Analyzers.AddLast(new VertexDegreeCalculator()); } if (checkedlist.vertex_reciprocated_pair_ratio == true) {args.Analyzers.AddLast(new ReciprocatedVertexPairRatioCalculator()); } if (checkedlist.vertex_clustering_coefficient == true) {args.Analyzers.AddLast(new ClusteringCoefficientCalculator()); } if (checkedlist.vertex_pagerank == true) { args.Analyzers.AddLast(new PageRankCalculator());} if (checkedlist.vertex_eigenvector_centrality == true) {} if (checkedlist.group_metrics == true) { args.Analyzers.AddLast(new GroupMetricCalculator());} // create a new BackgroundWorker m_oBackgroundWorker = new BackgroundWorker(); m_oBackgroundWorker.WorkerReportsProgress = true; m_oBackgroundWorker.WorkerSupportsCancellation = true; m_oBackgroundWorker.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork); m_oBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged); m_oBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorker_RunWorkerCompleted); m_oBackgroundWorker.RunWorkerAsync(args); }
//************************************************************************* // Method: CalculateGraphMetricsAsyncInternal() // /// <summary> /// Calculates one or more sets of graph metrics and stores the results in /// one or more worksheet columns. /// </summary> /// /// <param name="oCalculateGraphMetricsAsyncArgs"> /// Contains the arguments needed to asynchronously calculate graph /// metrics. /// </param> /// /// <param name="oBackgroundWorker"> /// A BackgroundWorker object. /// </param> /// /// <param name="oDoWorkEventArgs"> /// A DoWorkEventArgs object. /// </param> //************************************************************************* protected void CalculateGraphMetricsAsyncInternal( CalculateGraphMetricsAsyncArgs oCalculateGraphMetricsAsyncArgs, BackgroundWorker oBackgroundWorker, DoWorkEventArgs oDoWorkEventArgs ) { Debug.Assert(oCalculateGraphMetricsAsyncArgs != null); Debug.Assert(oBackgroundWorker != null); Debug.Assert(oDoWorkEventArgs != null); AssertValid(); IGraph oGraph = oCalculateGraphMetricsAsyncArgs.Graph; List<GraphMetricColumn> oAggregatedGraphMetricColumns = new List<GraphMetricColumn>(); CalculateGraphMetricsContext oCalculateGraphMetricsContext = new CalculateGraphMetricsContext( oCalculateGraphMetricsAsyncArgs.GraphMetricUserSettings, oBackgroundWorker); Boolean bDuplicateEdgesRemoved = false; foreach (IGraphMetricCalculator2 oGraphMetricCalculator in oCalculateGraphMetricsAsyncArgs.SortedGraphMetricCalculators) { if (!oGraphMetricCalculator.HandlesDuplicateEdges && !bDuplicateEdgesRemoved) { // This and the remainder of the graph metric calculators // cannot handle duplicate edges. Remove them from the graph. oGraph.Edges.RemoveDuplicates(); bDuplicateEdgesRemoved = true; } // Calculate the implementation's graph metrics. GraphMetricColumn [] aoGraphMetricColumns; if ( !oGraphMetricCalculator.TryCalculateGraphMetrics(oGraph, oCalculateGraphMetricsContext, out aoGraphMetricColumns) ) { // The user cancelled. oDoWorkEventArgs.Cancel = true; oBackgroundWorker.ReportProgress(0, new GraphMetricProgress("Cancelled.", false) ); return; } // Aggregate the results. Debug.Assert(aoGraphMetricColumns != null); oAggregatedGraphMetricColumns.AddRange(aoGraphMetricColumns); } oDoWorkEventArgs.Result = oAggregatedGraphMetricColumns.ToArray(); oBackgroundWorker.ReportProgress(100, new GraphMetricProgress( "Inserting metrics into the workbook.", true) ); // Let the dialog the display the final progress report and update its // controls. System.Threading.Thread.Sleep(1); }
//************************************************************************* // Method: CalculateGraphMetricsAsync() // /// <summary> /// Asynchronously calculates one or more sets of specified graph metrics /// and returns the results as an array of <see /// cref="GraphMetricColumn" /> objects. /// </summary> /// /// <param name="workbook"> /// Workbook containing the graph contents. /// </param> /// /// <param name="graphMetricCalculators"> /// An array of <see cref="IGraphMetricCalculator2" /> implementations, one /// for each set of graph metrics that should be calculated. This method /// sorts the array in place, so its contents will likely be in a different /// order when the method returns. /// </param> /// /// <param name="graphMetricUserSettings"> /// User settings for calculating graph metrics. /// </param> /// /// <remarks> /// For each <see cref="IGraphMetricCalculator2" /> implementation in the /// <paramref name="graphMetricCalculators" /> array, this method calls the /// implementation's <see /// cref="IGraphMetricCalculator2.TryCalculateGraphMetrics" /> method. The /// <see cref="GraphMetricColumn" /> objects returned by each /// implementation are aggregated. When graph metric calculations /// complete, the <see cref="GraphMetricCalculationCompleted" /> event /// fires and the aggregated results can be obtained via the <see /// cref="RunWorkerCompletedEventArgs.Result" /> property. /// /// <para> /// To cancel the calculations, call <see cref="CancelAsync" />. /// </para> /// /// <para> /// If <paramref name="workbook" /> contains invalid graph data, a <see /// cref="WorkbookFormatException" /> is thrown on the caller's thread /// before asynchronous calculations begin. /// </para> /// /// </remarks> //************************************************************************* public void CalculateGraphMetricsAsync( Microsoft.Office.Interop.Excel.Workbook workbook, IGraphMetricCalculator2 [] graphMetricCalculators, GraphMetricUserSettings graphMetricUserSettings ) { Debug.Assert(workbook != null); Debug.Assert(graphMetricCalculators != null); Debug.Assert(graphMetricUserSettings != null); AssertValid(); const String MethodName = "CalculateGraphMetricsAsync"; if (this.IsBusy) { throw new InvalidOperationException( String.Format( "{0}:{1}: An asynchronous operation is already in progress." , this.ClassName, MethodName ) ); } // Read the workbook into a graph. Do this from the calling thread to // avoid reading the Excel UI from a background thread. IGraph oGraph = ReadWorkbook(workbook, graphMetricUserSettings); // Sort the calculators so that those that can handle duplicate edges // are grouped at the beginning of the array. When the workbook is // read into a graph, duplicate edges are included and that graph is // passed to the first group of calculators. When the second group is // reached -- those that cannot handle duplicate edges -- the // duplicates are removed from the graph before passing the graph to // the second group. Array.Sort(graphMetricCalculators, (x, y) => y.HandlesDuplicateEdges.CompareTo(x.HandlesDuplicateEdges) ); // Wrap the arguments in an object that can be passed to // BackgroundWorker.RunWorkerAsync(). CalculateGraphMetricsAsyncArgs oCalculateGraphMetricsAsyncArgs = new CalculateGraphMetricsAsyncArgs(); oCalculateGraphMetricsAsyncArgs.Graph = oGraph; oCalculateGraphMetricsAsyncArgs.SortedGraphMetricCalculators = graphMetricCalculators; oCalculateGraphMetricsAsyncArgs.GraphMetricUserSettings = graphMetricUserSettings; // Create a BackgroundWorker and handle its events. m_oBackgroundWorker = new BackgroundWorker(); m_oBackgroundWorker.WorkerReportsProgress = true; m_oBackgroundWorker.WorkerSupportsCancellation = true; m_oBackgroundWorker.DoWork += new DoWorkEventHandler( BackgroundWorker_DoWork); m_oBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged); m_oBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler( BackgroundWorker_RunWorkerCompleted); m_oBackgroundWorker.RunWorkerAsync(oCalculateGraphMetricsAsyncArgs); }
CalculateGraphMetricsAsyncInternal ( CalculateGraphMetricsAsyncArgs oCalculateGraphMetricsAsyncArgs, BackgroundWorker oBackgroundWorker, DoWorkEventArgs oDoWorkEventArgs ) { Debug.Assert(oCalculateGraphMetricsAsyncArgs != null); Debug.Assert(oBackgroundWorker != null); Debug.Assert(oDoWorkEventArgs != null); AssertValid(); IGraph oGraph = oCalculateGraphMetricsAsyncArgs.Graph; List <GraphMetricColumn> oAggregatedGraphMetricColumns = new List <GraphMetricColumn>(); CalculateGraphMetricsContext oCalculateGraphMetricsContext = new CalculateGraphMetricsContext( oCalculateGraphMetricsAsyncArgs.GraphMetricUserSettings, oBackgroundWorker); Boolean bDuplicateEdgesRemoved = false; foreach (IGraphMetricCalculator2 oGraphMetricCalculator in oCalculateGraphMetricsAsyncArgs.SortedGraphMetricCalculators) { if (!oGraphMetricCalculator.HandlesDuplicateEdges && !bDuplicateEdgesRemoved) { // This and the remainder of the graph metric calculators // cannot handle duplicate edges. Remove them from the graph. oGraph.Edges.RemoveDuplicates(); bDuplicateEdgesRemoved = true; } // Calculate the implementation's graph metrics. GraphMetricColumn [] aoGraphMetricColumns; if (!oGraphMetricCalculator.TryCalculateGraphMetrics(oGraph, oCalculateGraphMetricsContext, out aoGraphMetricColumns)) { // The user cancelled. oDoWorkEventArgs.Cancel = true; oBackgroundWorker.ReportProgress(0, new GraphMetricProgress("Cancelled.", false) ); return; } // Aggregate the results. Debug.Assert(aoGraphMetricColumns != null); oAggregatedGraphMetricColumns.AddRange(aoGraphMetricColumns); } oDoWorkEventArgs.Result = oAggregatedGraphMetricColumns.ToArray(); oBackgroundWorker.ReportProgress(100, new GraphMetricProgress( "Inserting metrics into the workbook.", true) ); // Let the dialog the display the final progress report and update its // controls. System.Threading.Thread.Sleep(1); }
CalculateGraphMetricsAsync ( Microsoft.Office.Interop.Excel.Workbook workbook, IGraphMetricCalculator2 [] graphMetricCalculators, GraphMetricUserSettings graphMetricUserSettings ) { Debug.Assert(workbook != null); Debug.Assert(graphMetricCalculators != null); Debug.Assert(graphMetricUserSettings != null); AssertValid(); const String MethodName = "CalculateGraphMetricsAsync"; if (this.IsBusy) { throw new InvalidOperationException(String.Format( "{0}:{1}: An asynchronous operation is already in progress." , this.ClassName, MethodName )); } // Read the workbook into a graph. Do this from the calling thread to // avoid reading the Excel UI from a background thread. IGraph oGraph = ReadWorkbook(workbook, graphMetricUserSettings); // Sort the calculators so that those that can handle duplicate edges // are grouped at the beginning of the array. When the workbook is // read into a graph, duplicate edges are included and that graph is // passed to the first group of calculators. When the second group is // reached -- those that cannot handle duplicate edges -- the // duplicates are removed from the graph before passing the graph to // the second group. Array.Sort(graphMetricCalculators, (x, y) => y.HandlesDuplicateEdges.CompareTo(x.HandlesDuplicateEdges) ); // Wrap the arguments in an object that can be passed to // BackgroundWorker.RunWorkerAsync(). CalculateGraphMetricsAsyncArgs oCalculateGraphMetricsAsyncArgs = new CalculateGraphMetricsAsyncArgs(); oCalculateGraphMetricsAsyncArgs.Graph = oGraph; oCalculateGraphMetricsAsyncArgs.SortedGraphMetricCalculators = graphMetricCalculators; oCalculateGraphMetricsAsyncArgs.GraphMetricUserSettings = graphMetricUserSettings; // Create a BackgroundWorker and handle its events. m_oBackgroundWorker = new BackgroundWorker(); m_oBackgroundWorker.WorkerReportsProgress = true; m_oBackgroundWorker.WorkerSupportsCancellation = true; m_oBackgroundWorker.DoWork += new DoWorkEventHandler( BackgroundWorker_DoWork); m_oBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged); m_oBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler( BackgroundWorker_RunWorkerCompleted); m_oBackgroundWorker.RunWorkerAsync(oCalculateGraphMetricsAsyncArgs); }