CsWinRT icon indicating copy to clipboard operation
CsWinRT copied to clipboard

COMException (0x800401FD): Object is not connected to server (CO_E_OBJNOTCONNECTED)

Open jbe2277 opened this issue 2 years ago • 1 comments

Describe the bug I get a COMException (0x800401FD): Object is not connected to server (CO_E_OBJNOTCONNECTED) when calling Windows.Storage.Search.QueryOptions..ctor after application runs about 30 seconds.

When Windows.Storage.Search.QueryOptions..ctor is called immediately after the application was started then it works fine.

To Reproduce

  1. Build the following source with VS2022: https://github.com/jbe2277/musicmanager/releases/tag/v3.0.0
  2. Start the application
  3. Use the file navigation immediately after application was started -> works fine
  4. Wait about 30 seconds
  5. Use the file navigation -> the following exception occurs:
System.Runtime.InteropServices.COMException (0x800401FD): Objekt ist nicht mit dem Server verbunden. (0x800401FD (CO_E_OBJNOTCONNECTED))
   at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|20_0(Int32 hr)
   at Windows.Storage.Search.QueryOptions._IQueryOptionsFactory.CreateCommonFileQuery(CommonFileQuery query, IEnumerable`1 fileTypeFilter)
   at Windows.Storage.Search.QueryOptions.<>c__DisplayClass16_0.<.ctor>b__0()
   at Windows.Storage.Search.QueryOptions..ctor(CommonFileQuery query, IEnumerable`1 fileTypeFilter)
   at Waf.MusicManager.Presentation.Services.FileService.GetFiles(String directory, Boolean deep, String userSearchFilter, String applicationSearchFilter, CancellationToken cancellation)
   at Waf.MusicManager.Applications.Controllers.ManagerController.UpdateMusicFiles(Boolean deep)
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run()
   at Waf.MusicManager.Presentation.App.Main()

Version Info

  • .NET 6 / WPF application
  • Microsoft.Windows.SDK.NET: 10.0.18362.22
  • WinRT.Runtime: 1.4.0.37231

Workaround I was able to fix this issue by ensuring that Windows.Storage.Search.QueryOptions..ctor is called only in the WPF Dispatcher thread. However, creating an instance of QueryOptions should not be related with the Dispatcher thread.

See commit: https://github.com/jbe2277/musicmanager/commit/fd83633cf384a61148b7c0db8df990990fadf1b1

jbe2277 avatar Feb 22 '22 18:02 jbe2277

Issue looks to be that QueryOptions isn't agile which means the thread its factory was initially created in could matter and in this case it seems to.

The QueryOptions factory initially gets created during startup and is cached by CsWinRT, but then that thread goes away and when QueryOptions factory is called again, the cached entry is reused. But given it is not agile, we try to create an agile reference and marshal a pointer for the current thread. But the thread is gone and the fallback of using the raw pointer also fails given it seems the factory itself seems to rely on the thread.

We will need to add another fallback to reobtain the ActivationFactory for these cases or don't cache non agile activation factories.

manodasanW avatar Mar 11 '22 22:03 manodasanW