@@ -110,7 +110,8 @@ public AnalysisService(IConsoleHost consoleHost, string settingsPath = null)
110110 // need to worry about executing concurrent commands
111111 this . analysisRunspacePool = RunspaceFactory . CreateRunspacePool ( sessionState ) ;
112112
113- // one runspace for code formatting and the other for markers
113+ // having more than one runspace doesn't block code formatting if one
114+ // runspace is occupied for diagnostics
114115 this . analysisRunspacePool . SetMaxRunspaces ( 2 ) ;
115116 this . analysisRunspacePool . ThreadOptions = PSThreadOptions . ReuseThread ;
116117 this . analysisRunspacePool . Open ( ) ;
@@ -136,9 +137,9 @@ public AnalysisService(IConsoleHost consoleHost, string settingsPath = null)
136137 /// </summary>
137138 /// <param name="file">The ScriptFile which will be analyzed for semantic markers.</param>
138139 /// <returns>An array of ScriptFileMarkers containing semantic analysis results.</returns>
139- public ScriptFileMarker [ ] GetSemanticMarkers ( ScriptFile file )
140+ public async Task < ScriptFileMarker [ ] > GetSemanticMarkersAsync ( ScriptFile file )
140141 {
141- return GetSemanticMarkers ( file , activeRules , settingsPath ) ;
142+ return await GetSemanticMarkersAsync ( file , activeRules , settingsPath ) ;
142143 }
143144
144145 /// <summary>
@@ -147,9 +148,9 @@ public ScriptFileMarker[] GetSemanticMarkers(ScriptFile file)
147148 /// <param name="file">The ScriptFile to be analyzed.</param>
148149 /// <param name="settings">ScriptAnalyzer settings</param>
149150 /// <returns></returns>
150- public ScriptFileMarker [ ] GetSemanticMarkers ( ScriptFile file , Hashtable settings )
151+ public async Task < ScriptFileMarker [ ] > GetSemanticMarkersAsync ( ScriptFile file , Hashtable settings )
151152 {
152- return GetSemanticMarkers < Hashtable > ( file , null , settings ) ;
153+ return await GetSemanticMarkersAsync < Hashtable > ( file , null , settings ) ;
153154 }
154155
155156 /// <summary>
@@ -208,7 +209,7 @@ public void Dispose()
208209
209210 #region Private Methods
210211
211- private ScriptFileMarker [ ] GetSemanticMarkers < TSettings > (
212+ private async Task < ScriptFileMarker [ ] > GetSemanticMarkersAsync < TSettings > (
212213 ScriptFile file ,
213214 string [ ] rules ,
214215 TSettings settings ) where TSettings : class
@@ -218,23 +219,8 @@ private ScriptFileMarker[] GetSemanticMarkers<TSettings>(
218219 && ( typeof ( TSettings ) == typeof ( string ) || typeof ( TSettings ) == typeof ( Hashtable ) )
219220 && ( rules != null || settings != null ) )
220221 {
221- // TODO: This is a temporary fix until we can change how
222- // ScriptAnalyzer invokes their async tasks.
223- // TODO: Make this async
224- Task < ScriptFileMarker [ ] > analysisTask =
225- Task . Factory . StartNew < ScriptFileMarker [ ] > (
226- ( ) =>
227- {
228- return
229- GetDiagnosticRecords ( file , rules , settings )
230- . Select ( ScriptFileMarker . FromDiagnosticRecord )
231- . ToArray ( ) ;
232- } ,
233- CancellationToken . None ,
234- TaskCreationOptions . None ,
235- TaskScheduler . Default ) ;
236- analysisTask . Wait ( ) ;
237- return analysisTask . Result ;
222+ var scriptFileMarkers = await GetDiagnosticRecordsAsync ( file , rules , settings ) ;
223+ return scriptFileMarkers . Select ( ScriptFileMarker . FromDiagnosticRecord ) . ToArray ( ) ;
238224 }
239225 else
240226 {
@@ -324,23 +310,6 @@ private void InitializePSScriptAnalyzer()
324310 EnumeratePSScriptAnalyzerRules ( ) ;
325311 }
326312
327- private IEnumerable < PSObject > GetDiagnosticRecords ( ScriptFile file )
328- {
329- return GetDiagnosticRecords ( file , this . activeRules , this . settingsPath ) ;
330- }
331-
332- // TSettings can either be of type Hashtable or string
333- // as scriptanalyzer settings parameter takes either a hashtable or string
334- private IEnumerable < PSObject > GetDiagnosticRecords < TSettings > (
335- ScriptFile file ,
336- string [ ] rules ,
337- TSettings settings ) where TSettings : class
338- {
339- var task = GetDiagnosticRecordsAsync ( file , rules , settings ) ;
340- task . Wait ( ) ;
341- return task . Result ;
342- }
343-
344313 private async Task < IEnumerable < PSObject > > GetDiagnosticRecordsAsync < TSettings > (
345314 ScriptFile file ,
346315 string [ ] rules ,
@@ -366,7 +335,6 @@ private async Task<IEnumerable<PSObject>> GetDiagnosticRecordsAsync<TSettings>(
366335 settingArgument = rules ;
367336 }
368337
369-
370338 diagnosticRecords = await InvokePowerShellAsync (
371339 "Invoke-ScriptAnalyzer" ,
372340 new Dictionary < string , object >
@@ -392,31 +360,23 @@ private IEnumerable<PSObject> InvokePowerShell(string command, IDictionary<strin
392360
393361 private async Task < IEnumerable < PSObject > > InvokePowerShellAsync ( string command , IDictionary < string , object > paramArgMap )
394362 {
395- var task = Task . Run ( ( ) =>
363+ using ( var powerShell = System . Management . Automation . PowerShell . Create ( ) )
396364 {
397- using ( var powerShell = System . Management . Automation . PowerShell . Create ( ) )
365+ powerShell . RunspacePool = this . analysisRunspacePool ;
366+ powerShell . AddCommand ( command ) ;
367+ foreach ( var kvp in paramArgMap )
398368 {
399- powerShell . RunspacePool = this . analysisRunspacePool ;
400- powerShell . AddCommand ( command ) ;
401- foreach ( var kvp in paramArgMap )
402- {
403- powerShell . AddParameter ( kvp . Key , kvp . Value ) ;
404- }
405-
406- var powerShellCommandResult = powerShell . BeginInvoke ( ) ;
407- var result = powerShell . EndInvoke ( powerShellCommandResult ) ;
408-
409- if ( result == null )
410- {
411- return Enumerable . Empty < PSObject > ( ) ;
412- }
369+ powerShell . AddParameter ( kvp . Key , kvp . Value ) ;
370+ }
413371
414- return result ;
372+ var result = await Task . Factory . FromAsync ( powerShell . BeginInvoke ( ) , powerShell . EndInvoke ) ;
373+ if ( result == null )
374+ {
375+ return Enumerable . Empty < PSObject > ( ) ;
415376 }
416- } ) ;
417377
418- await task ;
419- return task . Result ;
378+ return result ;
379+ }
420380 }
421381
422382 #endregion //private methods
0 commit comments