dotnet / project-system

The .NET Project System for Visual Studio
MIT License
969 stars 387 forks source link

ObjectDisposedException during project close in up-to-date check Dataflow #7477

Closed RussKie closed 3 months ago

RussKie commented 3 years ago

Visual Studio Version: Version 17.0.0 Preview 4.0 [31608.29.main]

Summary:

System.ObjectDisposedException: 'Cannot access a disposed object.
Object name: 'Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory+RuntimeExportProvider'.'

image

System.ObjectDisposedException
  HResult=0x80131622
  Message=Cannot access a disposed object.
Object name: 'Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory+RuntimeExportProvider'.
  Source=Microsoft.VisualStudio.Validation
  StackTrace:
   at Microsoft.Verify.NotDisposed(IDisposableObservable disposedValue, String message)
   at Microsoft.VisualStudio.Composition.ExportProvider.<>c__DisplayClass63_0.<CreateExport>b__0()
   at Microsoft.VisualStudio.Composition.ExportProvider.<>c__DisplayClass52_3.<GetExports>b__5()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Microsoft.VisualStudio.Composition.ExportProvider.<>c__DisplayClass80_1`2.<GetExports>b__2()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Microsoft.VisualStudio.ProjectSystem.MefExtensions.GetExportedValueOrDefault[T](ExportProvider exportProvider)
   at Microsoft.VisualStudio.ProjectSystem.UpToDate.UpToDateCheckConfiguredInputDataSource.<>c.<LinkExternalInput>b__3_4(ConfiguredProject project) in C:\Development\project-system\src\Microsoft.VisualStudio.ProjectSystem.Managed\ProjectSystem\UpToDate\UpToDateCheckConfiguredInputDataSource.cs:line 39
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at Microsoft.VisualStudio.LinqExtensions.<WhereNotNull>d__2`1.MoveNext() in C:\Development\project-system\src\Microsoft.VisualStudio.ProjectSystem.Managed\LinqExtensions.cs:line 58
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Microsoft.VisualStudio.ProjectSystem.UnwrapCollectionChainedProjectValueDataSource`2.CreateOrUpdateLink(IProjectVersionedValue`1 sourceData, IImmutableDictionary`2 linkVersion, ITargetBlock`1 targetBlock, IDisposable currentLink)
   at Microsoft.VisualStudio.ProjectSystem.UnwrapChainedProjectValueDataSourceBase`2.<>c__DisplayClass15_0.<LinkExternalInput>b__1(IProjectVersionedValue`1 sourceData)
   at Microsoft.VisualStudio.ProjectSystem.ActionBlockSlimSync`1.ProcessInputAsync(TInput input)
   at Microsoft.VisualStudio.ProjectSystem.DataReceivingBlockSlim`1.<ProcessInputQueueAsync>d__5.MoveNext()

  This exception was originally thrown at this call stack:
    Microsoft.Verify.NotDisposed(Microsoft.IDisposableObservable, string)
    Microsoft.VisualStudio.Composition.ExportProvider.CreateExport.AnonymousMethod__0()
    Microsoft.VisualStudio.Composition.ExportProvider.GetExports.AnonymousMethod__5()
    System.Lazy<T>.CreateValue()
    System.Lazy<T>.LazyInitValue()
    Microsoft.VisualStudio.Composition.ExportProvider.GetExports.AnonymousMethod__2()
    System.Lazy<T>.CreateValue()
    System.Lazy<T>.LazyInitValue()
    Microsoft.VisualStudio.ProjectSystem.MefExtensions.GetExportedValueOrDefault<T>(Microsoft.VisualStudio.Composition.ExportProvider)
    Microsoft.VisualStudio.ProjectSystem.UpToDate.UpToDateCheckConfiguredInputDataSource.LinkExternalInput.AnonymousMethod__3_4(Microsoft.VisualStudio.ProjectSystem.ConfiguredProject) in UpToDateCheckConfiguredInputDataSource.cs
    ...
    [Call Stack Truncated]

Steps to Reproduce:

  1. I wan running an Exp instance from another VS
  2. I closed a solution in the Exp instance when the exception occurred
drewnoakes commented 3 years ago

This doesn't appear to be related to recent changes to the up-to-date check. @RussKie was this a first chance exception that cleaned itself up, or did VS crash?

The exception appears, to me at least, to suggest that the ExportProvider was disposed.

lifengl commented 3 years ago

It is a race condition during project closing. Configurations are teared down earlier than the unconfigured project level, so likely this code is running when configurations are being disposed. maybe need handle disposed configuration in this path. Also project.Services.AsyncService.UnloadCancellationToken will be triggered before all this, which might be useful to tear down works like that earlier.

lifengl commented 3 years ago

also, i noticed that your side is still using the Unwrap block, instead of switching to ConfiguredProjectDataSourceJoinBlock. I will suggest to use the new block in a future update.

drewnoakes commented 3 years ago

Thanks for the analysis Lifeng.

i noticed that your side is still using the Unwrap block, instead of switching to ConfiguredProjectDataSourceJoinBlock

This has been on my list for a while. I filed https://github.com/dotnet/project-system/issues/7483 to track it.

drewnoakes commented 3 years ago

We recently moved (nearly) all usages of OnceInitializedOnceDisposed* classes to use async disposal. That may be the cause of this exception.

drewnoakes commented 3 years ago

This code will change because of #7484, but I suspect the underlying race condition will remain.

kvenkatrajan commented 1 year ago

@drewnoakes can we confirm if this is still occuring

Dean-NC commented 5 months ago

This seems to still be happening, but could be something different. I see this in activitylog.xml when closing VS.

2461 End export of category 'Debugger' ({EEDBF29A-5C8B-4E01-827C-263382C18CFE}) from package 'Visual Studio Debugger' ({C9DD4A57-47FB-11D2-83E7-00C04F9902C1}) Profile manager
2462 Destroying Main Window

2463 ERROR A MEF Component threw an exception at runtime: System.ObjectDisposedException: Cannot access a disposed object. Microsoft.VisualStudio.ComponentModelHost.VsShellComponentModelHost
   Object name: 'Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory+RuntimeExportProvider+RuntimePartLifecycleTracker'.
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.ThrowIfDisposed()
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.ConstructExportedValue(RuntimeImport import, RuntimeExport export, RuntimePartLifecycleTracker importingPartTracker, PartLifecycleTracker partLifecycle, ReportFaultCallback faultCallback) Microsoft.VisualStudio.ComponentModelHost.VsShellComponentModelHost

2464 ERROR A MEF Component threw an exception at runtime: System.ObjectDisposedException: Cannot access a disposed object. Microsoft.VisualStudio.ComponentModelHost.VsShellComponentModelHost
  Object name: 'Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory+RuntimeExportProvider+RuntimePartLifecycleTracker'.
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.ThrowIfDisposed()
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.ConstructExportedValue(RuntimeImport import, RuntimeExport export, RuntimePartLifecycleTracker importingPartTracker, PartLifecycleTracker partLifecycle, ReportFaultCallback faultCallback)
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.GetExportedValue(RuntimeImport import, RuntimeExport export, RuntimePartLifecycleTracker importingPartTracker, Boolean lazy, PartLifecycleTracker& partLifecycle)
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.GetValueForImportElement(RuntimePartLifecycleTracker importingPartTracker, RuntimeImport import, RuntimeExport export, Func`3 lazyFactory)
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.GetValueForImportSite(RuntimePartLifecycleTracker importingPartTracker, RuntimeImport import)
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.<CreateValue>b__11_0(RuntimeImport import)
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.CreateValue()
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.Create()
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveToState(PartLifecycleState requiredState)
   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()
   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.ConstructExportedValue(RuntimeImport import, RuntimeExport export, RuntimePartLifecycleTracker importingPartTracker, PartLifecycleTracker partLifecycle, ReportFaultCallback faultCallback) Microsoft.VisualStudio.ComponentModelHost.VsShellComponentModelHost

2465 AppId stopped registry detouring
drewnoakes commented 3 months ago

@Dean-NC thanks for sharing the stacks. I think yours show something different. The key frame in the above stack is:

Microsoft.VisualStudio.ProjectSystem.UpToDate.UpToDateCheckConfiguredInputDataSource.<>c.b__3_4(ConfiguredProject project)`

I don't see any mention of UpToDate in your stack, or even ProjectSystem, so I don't think that failure is related to this repo. Unfortunately, I don't see anything on the stack there that identifies the component at fault. Maybe there's a task awaiting this exception during component construction. That makes it hard to know what component is at fault here.

drewnoakes commented 3 months ago

@lifengl do you remember seeing this exception since 17.0?

   at Microsoft.Verify.NotDisposed(IDisposableObservable disposedValue, String message)
   at Microsoft.VisualStudio.Composition.ExportProvider.<>c__DisplayClass63_0.<CreateExport>b__0()
   at Microsoft.VisualStudio.Composition.ExportProvider.<>c__DisplayClass52_3.<GetExports>b__5()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Microsoft.VisualStudio.Composition.ExportProvider.<>c__DisplayClass80_1`2.<GetExports>b__2()
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at Microsoft.VisualStudio.ProjectSystem.MefExtensions.GetExportedValueOrDefault[T](ExportProvider exportProvider)
   at Microsoft.VisualStudio.ProjectSystem.UpToDate.UpToDateCheckConfiguredInputDataSource.<>c.<LinkExternalInput>b__3_4(ConfiguredProject project) in C:\Development\project-system\src\Microsoft.VisualStudio.ProjectSystem.Managed\ProjectSystem\UpToDate\UpToDateCheckConfiguredInputDataSource.cs:line 39
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at Microsoft.VisualStudio.LinqExtensions.<WhereNotNull>d__2`1.MoveNext() in C:\Development\project-system\src\Microsoft.VisualStudio.ProjectSystem.Managed\LinqExtensions.cs:line 58
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Microsoft.VisualStudio.ProjectSystem.UnwrapCollectionChainedProjectValueDataSource`2.CreateOrUpdateLink(IProjectVersionedValue`1 sourceData, IImmutableDictionary`2 linkVersion, ITargetBlock`1 targetBlock, IDisposable currentLink)
   at Microsoft.VisualStudio.ProjectSystem.UnwrapChainedProjectValueDataSourceBase`2.<>c__DisplayClass15_0.<LinkExternalInput>b__1(IProjectVersionedValue`1 sourceData)
   at Microsoft.VisualStudio.ProjectSystem.ActionBlockSlimSync`1.ProcessInputAsync(TInput input)
   at Microsoft.VisualStudio.ProjectSystem.DataReceivingBlockSlim`1.<ProcessInputQueueAsync>d__5.MoveNext()

We haven't seen much signal on this. The code changed considerably in 17.0, which may have addressed this. I'll close this issue. We can re-open if it's reported again.