1

I'm trying to create a dialog from the WindowsAPICodePack in C#, but when it loads, it throws an exception that the calling thread can't access the object.

Exception: System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
   at System.Windows.Threading.Dispatcher.VerifyAccess()
   at System.Windows.Window.get_CriticalHandle()
   at System.Windows.Interop.WindowInteropHelper.get_CriticalHandle()
   at Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialog.ApplyNativeSettings(IFileDialog dialog)
   at Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialog.ShowDialog()

Code that creates exception:

CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = true;
CommonFileDialogResult result = dialog.ShowDialog();

I tried using Dispatcher.Invoke, but it still generated the same error. If I use the regular BrowserFolderDialog class it loads, but most likely this one doesn't load because it's from a different .dll file. How can the dialog be created in the same thread?

Matts
  • 1,301
  • 11
  • 30

1 Answers1

0

After playing a bit with the WindowsAPICodePack package (1.1.0) I can reproduce the problem if I call the CommonOpenFileDialog.ShowDialog() method from a thread other than the UI one.

I see that you mentioned that you tried the Dispatcher.Invoke() method, but that's actually working for me, please try this example to confirm:

using Microsoft.WindowsAPICodePack.Dialogs;
...
private void Button_Click(object sender, RoutedEventArgs e)
{
    System.Threading.Tasks.Task.Factory.StartNew(() =>
    {
        Dispatcher.Invoke(() =>
        {
            CommonOpenFileDialog dialog = new CommonOpenFileDialog();
            dialog.IsFolderPicker = true;
            CommonFileDialogResult result = dialog.ShowDialog();
        });
    });
}

On the other hand, without using Dispatcher.Invoke(...) it fails with the following exception:

System.InvalidOperationException: 'The calling thread cannot access this object because a different thread owns it.

yv989c
  • 1,453
  • 1
  • 14
  • 20
  • Thanks for your answer. It didn't work, but I think I realise more what the problem is now. I had encountered it previously with a new thread I created myself. The new thread isn't executed until a later time. It's calling the next method before it starts the new thread and generates the exception. – Matts Feb 10 '19 at 04:21