следующий код используется для запуска вызова (код сокращен, я не учел обработку ошибок в этом примере, чтобы сделать его более понятным)
public static void InvokeIfNecessary(this Control control, MethodInvoker methodInvoker)
{
if (control != null && !control.IsDisposed && !control.Disposing)
{
if (control.InvokeRequired)
{
control.Invoke(methodInvoker);
}
else
{
methodInvoker();
}
}
}
Обычно это работает нормально, но иногда, если я вызываю метод формы, выдается InvalidOperationException. Схематический метод, который будет называться
// in a Frm2:
internal void UpdateSomething()
{
List<NO> myObjects = frmMain.NO.GetNOs();
if (null != myObjects)
{
this.InvokeIfNecessary(() =>
{
layoutControlGroup.BeginUpdate(); // DevExpress Layoutcontrolgroup
foreach (NO aObject in myObjects)
{
if(...) // if already a control for the object exist update it.
{
// update
}
else
{
// add item
LayoutControlItem layoutControlItem = new LayoutControlItem();
// create new control
Control control = CreateNewControl(aObject);
layoutControlItem.Control = control;
// do some stuff with visibility and size of control
...
layoutControlGroup.AddItem(layoutControlItem); // <-- And here the InvalidOperationException occurs.
/// The message is (translated
/// InvalidOperationException was not handled by usercode
/// The acces on the Control FrmMain was done from another Thrad then the thread which created it.
...;
}
}
...;
layoutControlGroupCA.EndUpdate();
});
}
}
Что ж... Должен признать, что у меня тут концептуальная проблема.
Почему здесь выбрасывается исключение?
Метод Frm2 создает новый элемент (в НЕТ есть только строка и структура со строками и бул). Доступ к элементу возможен только внутри метода UpdateSomething(). Группа layOutControlGroup является членом Frm2.
Поэтому, на мой взгляд, только новый элемент управления, который должен быть создан в потоке Frm2, должен быть прикреплен к конкретному элементу управления Frm2.
Так почему же он настаивает на FrmMain? (основная форма, которая вызывает метод формы для информирования об обновлении элементов)
P.S. this.InvokeIfRequired ‹- на самом деле это Frm2...
Invoke
, если да, то не делайте этого. Если вы постоянно проверяете, даже когда знаете, что вам нужно будет вызывать, это просто расточительно и иногда доставляет вам боль в тех немногих случаях, когдаInvokeRequired
ложно, но вам действительно нужноInvoke
. - person Servy   schedule 06.06.2013