0

I've got a C# GUI applications that automates some Excel tasks via the official officer interop COM libraries. I'm providing my own event handler for the SheetActivate event.

// fetch the excel handle
var excel = viewer.GetApplication() as Microsoft.Office.Interop.Excel.Application;

// set sheet activate event handler
excel.SheetActivate += excel_SheetActivate;

I believe that the interop libraries call this event handler from a thread that it has created. My issues is that I need to update some GUI components based on this event, but I cannot perform update operations on the GUI across these threads.

My question is, from this excel interop event handler, which I believe is in its own thread, how can I safely update my GUI in a thread safe way?

I ask this because I am receiving run-time errors about cross thread operations while updating the GUI, currently.

Edit: I believe the linked and suggested possible answers are for WPF. My application is not WPF, it is the older WinForms. I do not see an Application.Current property.

Ryan
  • 867
  • 9
  • 23
  • See this : http://stackoverflow.com/questions/9732709/the-calling-thread-cannot-access-this-object-because-a-different-thread-owns-it – PaulF Sep 28 '16 at 16:35
  • Thanks for the link. That does seem to point me in the correct direction, but those answers seem to be for WPF. I'm using the older WinForms. I do not see an `Application.Current` property. – Ryan Sep 28 '16 at 17:34
  • @Ryan just use `someControl.Invoke(` from the control that is throwing the error, that will invoke the code on on the correct thread for that control. – Scott Chamberlain Sep 28 '16 at 17:50
  • Ah ok, gotcha. Thanks! – Ryan Sep 28 '16 at 18:03
  • Turned my comment in to a full answer. – Scott Chamberlain Sep 28 '16 at 21:13

1 Answers1

1

Just use

private void excel_SheetActivate(object activatedSheet)
{
    if (someControl.InvokeRequired)
    {
        someControl.Invoke((WorkbookEvents_SheetActivateEventHandler)excel_SheetActivate, activatedSheet);
    }
    else
    {
        someControl.Text = //...
    }
}

where someControl is the control that is throwing the error, that will check to see if a invoke is necessary, and if it is it will re-call the same function with the same arguments on the correct thread for that control.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431