Reputation: 6259
I have two dispatcher:
dispatcher1
dispatcher2
Now, when I call (this is a simplified sample of my complex code):
var ret = dispatcher1.Invoke(() => {
return dispatcher2.Invoke(() => {
return new object();
});
});
I will run in a deadlock.
the call of
dispatcher1.Invoke()
is now waiting in
DispatcherSynchronizationContext.Wait()
and also the dispatcher2 after calling
dispatcher2.Invoke()
is waiting in
DispatcherSynchronizationContext.Wait
I cannot change the Invoke-Calls to async calls (BeginInvoke) because I need the result.
This was not the case with .NET 4.0 - only since I have changed to .NET 4.5.
Is there a way to solve this?
Upvotes: 3
Views: 1498
Reputation: 25623
But if you feel like living dangerously, try replacing your Invoke
calls with the InvokeAndPump
extension method below. (Don't replace every call to Invoke
in your project--just the problematic ones in the question.)
public static class DispatcherExtensions
{
public static T InvokeAndPump<T>(
this Dispatcher dispatcher,
Func<T> function,
DispatcherPriority priority = DispatcherPriority.Normal)
{
if (dispatcher == null)
throw new ArgumentNullException("dispatcher");
if (function == null)
throw new ArgumentNullException("function");
// If you've found this code in your project, you are doomed. <3
Action wait, notify;
var currentDispatcher = Dispatcher.FromThread(Thread.CurrentThread);
if (currentDispatcher != null)
{
var frame = new DispatcherFrame();
wait = () => Dispatcher.PushFrame(frame);
notify = () => frame.Continue = false;
}
else
{
var waitEvent = new ManualResetEventSlim(false);
wait = waitEvent.Wait;
notify = waitEvent.Set;
}
var error = default(Exception);
var result = default(T);
dispatcher.BeginInvoke(
priority,
new Action(
() =>
{
try { result = function(); }
catch (Exception e) { error = e; }
finally { notify(); }
}));
// Hold on to your butts...
wait();
if (error != null)
throw new TargetInvocationException(error);
return result;
}
}
Seriously, though: heaven help anyone who uses this and expects it to work reliably. I'm only posting it out of curiosity and because I am evil. Mostly the evil.
Upvotes: 4