One of our clients has reported an issue with one of our Add-ins becoming unresponsive. The error reported contains a stack trace that goes deep into the bowels of WPF and I won't distract you with that. Suffice to say that the top level error reads:
Dispatcher processing has been suspended, but messages are still being processed.
The same code works perfectly on my, and as far as I know any other, machine. All the code does is instantiate a WPF window and call its .ShowDialog() method.
Looking through issues with the same error, I find answers such as this: Dispatcher throws InvalidOperationException on Messagebox.Show in Textchanged event or WPF : Dispatcher processing has been suspended, but messages are still being processed
In both cases the answer provided is to use Dispatcher.BeginInvoke
The problem with that is that this call is asynchronous and I need to wait for user response. So I use Dispatcher.Invoke instead:
Dispatcher.Invoke(Sub() oAIC.ShowDialog(), System.Windows.Threading.DispatcherPriority.Normal)
Once again this works perfectly on my machine but that means nothing. The original code worked perfectly on my machine, too.
So my question is:
Is this even worth pursuing? Or is the fact that I use .Invoke instead of .BeginInvoke equivalent to me just using the original .ShowDialog() directly so I'm wasting my time?
Suffice to say that the client in question is not of the cooperative kind. Other clients would be happy for me to give them a trial version and report back, but this person simply wants a solution and doesn't want to be bothered with anything else. As this has never been reported by any other client I can't even find another "guinea pig" to try this on, so all I have left is the option to ask it here in the hope that someone with sufficient expertise can tell me "yes this is a good way forward" or "you're wasting your time". Sorry if this doesn't quite fit the model for asking questions here but I'm at the end of my rope...
further clarification after seeing Peregrine's answer
The code is part of an Office Add-in (in this case for Microsoft Word). The WPF dialog I'm trying to display pops up several levels down from a button click in the Ribbon Bar.
I put the code behind the button click into a function
DoTheButtonCode()
and called it as follows
Await System.Threading.Tasks.Task.Run(AddressOf DoTheButtonCode)
When I tried this, an error was raised:
An exception of type 'System.InvalidOperationException' occurred in PresentationCore.dll but was not handled in user code Additional information: The calling thread must be STA, because many UI components require this.
Now this is the weird thing. In the original Button Click event, the apartmentstate of system.threading.thread.currentthread is STA but when I then step into the DoTheButtonCode and I check system.threading.thread.currentthread its apartmentstate is MTA
further clarification
Ok - tried something else:
Changed DoTheButtonCode to an Async Function:
Private Async Function DoTheButtonCode() As Threading.Tasks.Task(Of Integer)
The button Click event handler method is now defined Private Async Sub, and within it I call
Await DoTheButtonCode()
This actually works, apart from this niggling warning that appears in the function definition of DoTheButtonCode: "this async method lacks 'Await' operators and so will run synchronously" (etc)
So while this does work I suspect that I'm kidding myself here.
I think I'm about ready to give up. I'll just add a try/catch construct around my original ShowDialog call and if the error is raised at least it will simply do nothing rather than crash :(
Thanks for all your help, Peregrine