提交 1df7271b 编写于 作者: K Kevin Pilch-Bisson

Wait 5 seconds before reloading metadata on a change

Fixes #12189, and restores the behavior of the native C# language service.

The problem here is that we frequently get the file change notification
while something is still writing the file, and so we get an IOException when
we try to read it, resulting in us caching empty metadata and reporting
spurious errors.
上级 e1781933
......@@ -6,6 +6,8 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
......@@ -15,7 +17,6 @@
using Microsoft.CodeAnalysis.Notification;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.TextManager.Interop;
......@@ -23,6 +24,8 @@
using Roslyn.Utilities;
using VSLangProj;
using VsHierarchyPropID = Microsoft.VisualStudio.Shell.VsHierarchyPropID;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
{
internal abstract partial class AbstractProject : IVisualStudioHostProject
......@@ -108,6 +111,9 @@ internal abstract partial class AbstractProject : IVisualStudioHostProject
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true);
private readonly Dictionary<VisualStudioMetadataReference, CancellationTokenSource> _changedReferencesPendingUpdate
= new Dictionary<VisualStudioMetadataReference, CancellationTokenSource>();
public AbstractProject(
VisualStudioProjectTracker projectTracker,
Func<ProjectId, IVsReportExternalErrors> reportExternalErrorCreatorOpt,
......@@ -586,6 +592,28 @@ private void OnImportChanged(object sender, EventArgs e)
{
VisualStudioMetadataReference reference = (VisualStudioMetadataReference)sender;
CancellationTokenSource delayTaskCancellationTokenSource;
if (_changedReferencesPendingUpdate.TryGetValue(reference, out delayTaskCancellationTokenSource))
{
delayTaskCancellationTokenSource.Cancel();
}
delayTaskCancellationTokenSource = new CancellationTokenSource();
_changedReferencesPendingUpdate[reference] = delayTaskCancellationTokenSource;
var task = Task.Delay(TimeSpan.FromSeconds(5), delayTaskCancellationTokenSource.Token)
.ContinueWith(
OnImportChangedAfterDelay,
reference,
delayTaskCancellationTokenSource.Token,
TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
}
private void OnImportChangedAfterDelay(Task previous, object state)
{
var reference = (VisualStudioMetadataReference)state;
_changedReferencesPendingUpdate.Remove(reference);
// Ensure that we are still referencing this binary
if (_metadataReferences.Contains(reference))
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册