2016-09-28 3 views
0

У меня есть приложения C# GUI, которые автоматизируют некоторые задачи Excel через официальные офицеры interop COM-библиотек. Я предоставляю свой собственный обработчик событий для события .Как обновить элементы управления графическим интерфейсом из потока событий взаимодействия между приложениями Excel?

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

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

Я считаю, что библиотеки interop вызывают этот обработчик событий из потока, который он создал. Мои проблемы в том, что мне нужно обновить некоторые компоненты GUI на основе этого события, но я не могу выполнять операции обновления в графическом интерфейсе через эти потоки.

Вопрос в том, из этого обработчика событий excel interop, который, как я считаю, находится в собственном потоке, как я могу безопасно обновлять свой графический интерфейс потоком безопасным способом?

Я спрашиваю об этом, потому что в настоящее время я получаю ошибки во время выполнения операций поперечного потока при обновлении GUI.

Редактировать: Я считаю, что связанные и предлагаемые возможные ответы для WPF. Мое приложение не WPF, это старые WinForms. Я не вижу Application.Current.

+0

Смотрите это: http://stackoverflow.com/questions/9732709/the-calling-thread-cannot-access-this-object-because-a-different-thread-owns-it – PaulF

+0

Спасибо за ссылку. Это, кажется, указывает мне в правильном направлении, но эти ответы, похоже, для WPF. Я использую старые WinForms. Я не вижу свойство «Application.Current». – Ryan

+0

@Ryan просто используйте 'someControl.Invoke (' из элемента управления, который выдает ошибку, которая будет вызывать код в правильной нити для этого элемента управления. –

ответ

1

Просто используйте

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

где someControl является контроль, который бросает ошибку, которая будет проверять, чтобы увидеть, если Invoke необходимо, и если она будет повторно вызывать такую ​​же функцию с тем же аргументы в правильной теме для этого элемента управления.