Cannot convert lambda expression to type 'System.Delegate'
Asked Answered
E

4

58

Neither of these work:

_uiDispatcher.Invoke(() => { });
_uiDispatcher.Invoke(delegate() { });

All I want to do is Invoke an inline method on my main UI thread. So I called this on the main thread:

_uiDispatcher = Dispatcher.CurrentDispatcher;

And now I want to execute some code on that thread from another thread. How do I do it? Am I using the wrong syntax?

Note that this is not a WPF application; I've referenced WindowsBase so I could get access to the Dispatcher class.

Eserine answered 3/3, 2012 at 19:56 Comment(3)
What type is _uiDispatcher? Did you use the UI's synchronized object?Tereus
uiDispatcher is an instance of msdn.microsoft.com/en-us/library/…. I thought that was implicit from _uiDispatcher = Dispatcher.CurrentDispatcher. "The UI" doesn't have a synchronized object AFAIK....but how would I use it? What would do that do for me?Eserine
Ah ...ok, I don't think the thread dispatcher is going to work. Is this a WinForm application?Tereus
T
82

The problem is that you aren't providing the exact type of delegate you want to invoke. Dispatcher.Invoke just takes a Delegate. Is it an Action<T>? If so, what is T? Is it a MethodInvoker? Action? What?

If your delegate takes no arguments and returns nothing, you can use Action or MethodInvoker. Try this:

_uiDispatcher.Invoke(new Action(() => { }));
Ti answered 3/3, 2012 at 20:1 Comment(2)
I guess I'm used to most methods that accept a delegate provide a signature, so I don't need to specify one. This makes sense though. Thanks!Eserine
I don't think this works how I thought it would. The method never seems to get invoked; I'm guessing that WPF usually handles that for you and periodically executes those methods? Perhaps I should just a Queue<Action> and manage this myself then...Eserine
C
7
 this.Dispatcher.Invoke((Action)(() => { textBox1.Text = "Test 123"; }));
Cliftonclim answered 3/10, 2014 at 6:22 Comment(0)
S
2

Expanding on other answers a little.

Action with no parameters:

_uiDispatcher.Invoke(new Action(() =>
{
    // Do stuff
    textBox1.Text = "Test 123";
}));

Action with 1 parameter:

_uiDispatcher.Invoke(new Action<bool>((flag) =>
{
    if (flag)
    {
        // Do stuff
        textBox1.Text = "Test 123";
    }

}));

Action with 2 parameters:

_uiDispatcher.Invoke(new Action<int, string>((id, value) =>
{
    // Do stuff
    textBox1.Text = $"{value} {id}";
}));

And so on...

Soho answered 13/4, 2021 at 16:42 Comment(0)
T
0

Unless I've missed something, all you've told us is this is not a WPF application. I don't think the Dispatcher is the correct class to use.

If this is a WinForm app, your UI thread can be accessed via the WindowsFormsSynchronizationContext

Tereus answered 4/3, 2012 at 0:41 Comment(1)
It's not a WinForm app either; I'm using OpenGL. OpenGL uses a GL context, and you can only draw to it from the same thread it was created on. I was trying to come up with a way to run some stuff on the main thread... I've used Dispatcher in a WPF app before, so I thought I could use it again to solve this problem.Eserine

© 2022 - 2024 — McMap. All rights reserved.