У меня есть форма с моими настраиваемыми элементами управления.Работа с перекрестными потоками недействительна, даже если используется InvokeRequired
У меня есть метод в моей форме:
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
ветви я получаю Упомянутый исключение:
Cross-thread operation not valid: Control 'txtNumber' accessed from a thread other than the thread it was created on.
Мой сценарий на самом деле немного сложнее - Я просто экстраполировал это как пример. Что на самом деле происходит, так это то, что я использую WorkflowFoundation - у меня есть StateMachineActivity (CTP1), работающий в WorkflowApplication (который работает в собственном потоке), я подписался на это событие, а оттуда я звоню SetEnabledOnControls
. Кроме того, я использую закладки для возобновления рабочего процесса (а также MEF на стороне, не участвующей в сценарии).
Все это не имеет отношения к моему явному непониманию InvokeRequired - как возможно, что если InvokeRequired является ложным, у меня есть перекрестное резьбовое исключение? Я не создаю никаких элементов управления вручную - это все, что есть в инициализации(), созданной дизайнером.
Может ли кто-нибудь пролить свет на это?
Спасибо!
EDIT Используя GWLlosa предложение, я отслеживал ThreadId с помощью System.Threading.Thread.CurrentThread.ManagedThreadId
. Теперь наступает странная часть ... Идентификатор потока в Initialize() равен 10. Между прохождением первых 2 состояний он входит в Id 13 - InvokeRequired был true, и он вызывался правильно. НО, после второго состояния, когда он входит в SetEnabledOnControls
, это снова 13, но на этот раз InvokeRequired является ложным! Как так!? Позже, конечно, он не может изменить контроль над детьми (не удивительно). Может быть, форма как-то изменила нить, в которой она живет?
EDIT 2 Теперь я звоню с:
if (IsHandleCreated)
{
Invoke((Action<bool>)SetEnabledOnControls, val);
}
и имеет IsHandleCreated
к истинным, но все еще не с чем devSpeed pointed at.
EDIT 3 FACEPALM :) Одна из кнопок, которые были возобновления состояние было в первом CancelButton для формы. Когда он был удален из свойства как такового, у кода еще был DialogResult = Отмена для него - так что моя форма действительно закрывалась, и, конечно, у него отсутствовал дескриптор, поэтому InvokeRequired не возвращал правильную информацию и, следовательно, ошибки ,
Спасибо всем! Сегодня я узнал что-то новое :)
Действительно я столкнулся с этим в конце ... полезная ссылка;) – veljkoz 2010-12-17 12:56:18