I always thought I could use SynchronizationContext to marshal a call to another thread. Apparently I was wrong as SyncCtx.Send() doesn't do anything but invoking the given delegate (stays on the same thread). Do I really need to derive from SynchronizationContext and do work on the thread context? I feel like missing something.
What I want to achive: Imagine a little API for executing commands within an app. You can also execute a command on a background thread, as you can assign a delegate to run when the command has finished execution. This "Call-me-when-done"-Delegate gets one single paramter (State) containing success/failure flag, optional exception information, etc. I want to call this delegate on the original calling thread so that devs using the lib do not need to handle invoke required etc. I would just like to take this away and let them do simple non-thread-aware programming. WindowsFormsSynchronizationContext doesn't seem to help either if you don't give it some control as a target.
Thanks for any help!
When you are in winforms and you use the synchronizationcontext the call will be marshalled to the GUI thread.
for your specific case I guess something like this should work, probably it will be a good idea to create a class that represents a Command
public class CommandManager
{
private readonly SynchronizationContex _synchronizationContex;
public CommandManager(SynchronizationContext synchronizationContex)
{
_synchronizationContex = synchronizationContex;
}
public void ExecuteAsync(Func<State> action, Action<State> callback)
{
ThreadPool.QueueUserWorkItem(o => {
state = action();
_synchronizationContex.Send(oo => callback(state));
});
}
}
you'd create like this (in the GUI thread, so for example in your main form)
var commandManager = new CommandManager(SynchronizationContext.Current);
you'd use it like this:
commandManager.ExecuteAsync(() => new State() { Success = true },
c => MessageBox.Show("success in the GUI thread"));