У меня есть форма с мои пользовательские элементы управления на нем.
У меня есть метод в моей форме:
private void SetEnabledOnControls(bool val)
{
if (InvokeRequired)
{
Invoke((Action<bool>)SetEnabledOnControls, val);
}
else
{
//do the work - iterate over child controls,
//and they iterate over their children, etc...
}
}
И внутри методов, которые находятся в ветке else
, я получаю упомянутое исключение:
Межпоточная операция не действительный: элемент управления 'txtNumber' доступен из потока, отличного от потока, в котором он был создан.
Мой сценарий на самом деле немного сложнее - я просто экстраполировал его в качестве примера. На самом деле происходит то, что я использую WorkflowFoundation - У меня есть StateMachineActivity (CTP1), работающий в WorkflowApplication (который работает в собственном потоке), я подписался на это событие, и оттуда я вызываю SetEnabled OnControls
. Кроме того, я использую закладки, чтобы возобновить рабочий процесс (а также есть MEF на стороне, не участвующей в сценарии).
Все это не имеет отношения к моему очевидному непониманию InvokeRequired - как это возможно, что если InvokeRequired имеет значение false, у меня возникнет перекрестное исключение? Я не создаю никаких элементов управления «вручную» - все это есть в Initialize (), созданном дизайнером.
Кто-нибудь может пролить свет на это?
Спасибо!
ИЗМЕНИТЬ
Используя предложение GWLlosa, я отследил ThreadId с помощью System.Threading.Thread.CurrentThread.ManagedThreadId
. А теперь самое странное ... идентификатор потока в Initialize () равен 10. Между передачей первых двух состояний он приходит с идентификатором 13 - InvokeRequired был истинным и вызывается правильно. НО после второго состояния, когда он входит в SetEnabledOnControls
, снова 13, но на этот раз InvokeRequired ложно! Как придешь!? Позже, конечно, не удается изменить дочерние элементы управления (что неудивительно). Может быть, форма каким-то образом изменила поток, в котором живет ??
РЕДАКТИРОВАТЬ 2 Теперь я звоню с помощью:
if (IsHandleCreated)
{
Invoke((Action<bool>)SetEnabledOnControls, val);
}
, и у него IsHandleCreated
значение true , но по-прежнему не работает с тем, что devSpeed указал на .
РЕДАКТИРОВАТЬ 3 FACEPALM :) Одна из кнопок, которые возвращались в состояние, сначала была CancelButton для формы. Когда он был удален из свойства как такового, у codebihind все еще был DialogResult = Cancel для него - так что моя форма действительно закрывалась, и, конечно, в ней отсутствовал дескриптор, поэтому InvokeRequired не возвращал правильную информацию, и, следовательно, ошибки .
Спасибо всем! Сегодня я узнал новое:)