Skip to content

Commit 40b0e13

Browse files
author
Kapil Borle
committed
Make GetScriptFileMarkers method async
1 parent a2e689b commit 40b0e13

File tree

2 files changed

+23
-65
lines changed

2 files changed

+23
-65
lines changed

src/PowerShellEditorServices.Protocol/Server/LanguageServer.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ private async Task HandleScriptFileMarkersRequest(
239239
ScriptFileMarkerRequestParams requestParams,
240240
RequestContext<ScriptFileMarkerRequestResultParams> requestContext)
241241
{
242-
var markers = editorSession.AnalysisService.GetSemanticMarkers(
242+
var markers = await editorSession.AnalysisService.GetSemanticMarkersAsync(
243243
editorSession.Workspace.GetFile(requestParams.filePath),
244244
editorSession.AnalysisService.GetPSSASettingsHashtable(requestParams.settings));
245245
await requestContext.SendResult(new ScriptFileMarkerRequestResultParams {
@@ -1247,9 +1247,7 @@ private static async Task DelayThenInvokeDiagnostics(
12471247
{
12481248
Logger.Write(LogLevel.Verbose, "Analyzing script file: " + scriptFile.FilePath);
12491249

1250-
semanticMarkers =
1251-
editorSession.AnalysisService.GetSemanticMarkers(
1252-
scriptFile);
1250+
semanticMarkers = await editorSession.AnalysisService.GetSemanticMarkersAsync(scriptFile);
12531251

12541252
Logger.Write(LogLevel.Verbose, "Analysis complete.");
12551253
}

src/PowerShellEditorServices/Analysis/AnalysisService.cs

Lines changed: 21 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)