I need to "send" a piece of code from another thread (Excel Interop) to the UI thread to execute. Normally you'd use Invoke
on the Form
, which implements the ISynchronizeInvoke
interface:
public class MyForm : Form
{
...
private void Button_Click(object sender, EventArgs e)
{
SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel)
{
this.Invoke(someCode);
};
}
}
Unfortunately there is a layer of abstraction between the form code and the code that defines the event handler, and I don't have a reference to the form at that point:
public void CodeExecutedByUIThread()
{
ISynchronizeInvoke sync;
SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel)
{
sync.Invoke(someCode);
};
}
When entering CodeExecutedByUIThread
, we are still in the UI thread, so in theory everything needed should be there. Unfortunately the Form is the only class implementing that interface, is it?
How can I get an ISynchronizeInvoke
from within the UI thread? Apparently Thread.CurrentThread
doesn't provide it...
Or is there a way to get a SynchronizationContext
? How would I retrieve and use that?
Update: Oh, I see, getting the SynchronizationContext object looks as simple as SynchronizationContext.Current
, which doesn't need any reference to a form. So I'll google little bit more about how to use that.
In general, I think that neither is possible.
This might seem like an obvious answer, but what we used in this case was to store both the SynchronizationContext and the reference to the Form (as an ISynchronizeInvoke) in a static class at application startup.
MainForm main = new MainForm();
EnvironmentService.UI = main;
EnvironmentService.UIContext = SynchronizationContext.Current;
Application.Run(main);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With