|
1 | 1 | // Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information.
|
2 | 2 |
|
3 |
| -using System.Diagnostics.CodeAnalysis; |
4 | 3 | using System.Runtime.Versioning;
|
5 | 4 | using Microsoft.DotNet.HotReload;
|
6 | 5 | using Microsoft.VisualStudio.Debugger.Contracts.EditAndContinue;
|
@@ -72,16 +71,6 @@ internal static string GetInjectedAssemblyPath(string targetFramework, string as
|
72 | 71 | public IDeltaApplier? DeltaApplier
|
73 | 72 | => _lazyDeltaApplier;
|
74 | 73 |
|
75 |
| - [MemberNotNull(nameof(_lazyDeltaApplier))] |
76 |
| - private void RequireActiveSession() |
77 |
| - { |
78 |
| - if (!_sessionActive) |
79 |
| - throw new InvalidOperationException($"Hot Reload session has not started"); |
80 |
| - |
81 |
| - if (_lazyDeltaApplier is null) |
82 |
| - throw new InvalidOperationException(); |
83 |
| - } |
84 |
| - |
85 | 74 | public async Task ApplyChangesAsync(CancellationToken cancellationToken)
|
86 | 75 | {
|
87 | 76 | if (_sessionActive)
|
@@ -199,19 +188,29 @@ public async Task StartSessionAsync(CancellationToken cancellationToken)
|
199 | 188 |
|
200 | 189 | public async Task StopSessionAsync(CancellationToken cancellationToken)
|
201 | 190 | {
|
202 |
| - RequireActiveSession(); |
203 |
| - |
204 |
| - _sessionActive = false; |
205 |
| - _lazyDeltaApplier.Dispose(); |
206 |
| - _lazyDeltaApplier = null; |
| 191 | + if (_sessionActive && _lazyDeltaApplier is not null) |
| 192 | + { |
| 193 | + _sessionActive = false; |
| 194 | + _lazyDeltaApplier.Dispose(); |
| 195 | + _lazyDeltaApplier = null; |
207 | 196 |
|
208 |
| - await _hotReloadAgentManagerClient.Value.AgentTerminatedAsync(this, cancellationToken); |
209 |
| - WriteToOutputWindow(Resources.HotReloadStopSession, default); |
| 197 | + await _hotReloadAgentManagerClient.Value.AgentTerminatedAsync(this, cancellationToken); |
| 198 | + WriteToOutputWindow(Resources.HotReloadStopSession, default); |
| 199 | + } |
210 | 200 | }
|
211 | 201 |
|
212 | 202 | public async ValueTask ApplyUpdatesAsync(ImmutableArray<ManagedHotReloadUpdate> updates, CancellationToken cancellationToken)
|
213 | 203 | {
|
214 |
| - RequireActiveSession(); |
| 204 | + // A stricter check for session active could be done here, like raise an exception when not active session or no delta applier |
| 205 | + // But sometimes debugger would call ApplyUpdatesAsync even when there is not active session |
| 206 | + // e.g. when user restarts on rude edits |
| 207 | + // We need to talk to debugger team to see if we can avoid such calls in the future |
| 208 | + // https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2581474 |
| 209 | + if (_sessionActive is false || _lazyDeltaApplier is null) |
| 210 | + { |
| 211 | + DebugTrace($"{nameof(ApplyUpdatesAsync)} called but the session is not active."); |
| 212 | + return; |
| 213 | + } |
215 | 214 |
|
216 | 215 | try
|
217 | 216 | {
|
@@ -248,11 +247,15 @@ private bool LogAndPropagate(Exception e, CancellationToken cancellationToken)
|
248 | 247 | return false;
|
249 | 248 | }
|
250 | 249 |
|
251 |
| - public ValueTask<ImmutableArray<string>> GetCapabilitiesAsync(CancellationToken cancellationToken) |
| 250 | + public async ValueTask<ImmutableArray<string>> GetCapabilitiesAsync(CancellationToken cancellationToken) |
252 | 251 | {
|
253 |
| - RequireActiveSession(); |
| 252 | + // Delegate to the delta applier for the session |
| 253 | + if (_lazyDeltaApplier is not null) |
| 254 | + { |
| 255 | + return await _lazyDeltaApplier.GetCapabilitiesAsync(cancellationToken); |
| 256 | + } |
254 | 257 |
|
255 |
| - return _lazyDeltaApplier.GetCapabilitiesAsync(cancellationToken); |
| 258 | + return []; |
256 | 259 | }
|
257 | 260 |
|
258 | 261 | public ValueTask ReportDiagnosticsAsync(ImmutableArray<ManagedHotReloadDiagnostic> diagnostics, CancellationToken cancellationToken)
|
|
0 commit comments