2014-08-29 1 views
0

Итак, у меня первоначально был этот раздел кода, в котором родительский вызывающий объект в дереве вызывающего абонента является функцией загрузки моего главного окна. Теперь это дало мне startInvoke (ваш контроль Windows еще не инициализирован и он пытается ссылаться на него) при каждом перезагрузке моей ОС. Многие предложили переместить его в отображаемое событие формы, чтобы добавить логическое значение, если что-то было загружено, но это никогда не избавлялось от этой проблемы. Я закончил тем, что просто удалил многопоточность, так как я вытаскивал свои волосы.Проверка Threading на Invoke

 'send broadcast on network  
    Dim tasksArr(1) As Task 
    Dim brand1SearchTask= Task(Of List(Of device)).Factory.StartNew(Function() getbrand1()) 
    Dim brand2SearchTask= Task(Of List(Of device)).Factory.StartNew(Function() getbrand2()) 

    Try 
     tasksArr(0) = brand1SearchTask 
     tasksArr(1) = brand2SearchTask 
     Task.WaitAll(tasksArr) 
    Catch ex As Exception 

    End Try 

    Try 
     Try 
      deviceList.AddRange(brand1SearchTask.Result()) 
     Catch ex As Exception 
     End Try 

     deviceList.AddRange(brand2SearchTask.Result()) 
    Catch ex As Exception 

    End Try 

Этот код находится в пределах функции в отдельном классе NetworkSearch.FindDevices(). Он вызывается из функции загрузки в MainWindow_Load.

Итак, из того, что я узнал, основная проблема заключается в том, что в задании .start или begin call он вызывает .Invoke, и если моя форма не инициализируется в это время, она будет жаловаться из окон. Одним из решений было создание отдельного модуля, а затем создание новой() формы моего главного окна. Это устранило ошибку, но любые другие формы из этого окна (например, нажатие кнопки для запуска другой формы) также не были инициализированы и дали мне нулевое исключение.

Мой вопрос: Что такое хороший способ проверить, инициализирован ли я еще в задачах или потоковой среде, а затем ждать, чтобы войти в мои темы? Если бы это был элемент управления, я бы создал функцию делегата и отредактировал его, но здесь это не касается напрямую GUI.

То, что я пробовал:

-Создание модуля и сделать новую() основную форму от него, но потом всех остальных моих форм были ничем не возражает, когда запущенно оттуда

-Moved в появившейся форме в главной форме (начинать вызывать ошибку до сих пор)

-Добавлено приватное приложение My_application для обработки me.startup с помощью My.Settings.Loadfinished boolean, не удалял его.

-Добавлена ​​«mainwindow.invokerequired» проверить, жаловался только на время выполнения, что нужно было сказать «я» вместо

ответ

0

Если вы хотите создать класс, чтобы иметь возможность выполнить код конкретно в потоке пользовательского интерфейса когда это она не имеет прямого знания о пользовательском интерфейсе, то у вас есть два основных варианта:

  1. Объявите SynchronizingObject свойство в классе типа ISynchronizeInvoke. Внутри проверьте, является ли это свойство Nothing, и, если это не так, используйте его свойство InvokeRequired и метод Invoke/BeginInvoke. С внешней стороны вы можете назначить форму или другой элемент управления этому свойству. Так работают классы FileSystemWatcher и Timers.Timer.

  2. Объявление поля в вашем классе типа SynchronizationContext и его инициализация SynchroinizationContext.Current. Если ваш экземпляр класса создается в потоке пользовательского интерфейса, то это поле не будет Nothing, и вы можете использовать его метод /Post.