Это установщик свойства Control.Text
:
set
{
// some code omitted
this.WindowText = value;
this.OnTextChanged(EventArgs.Empty);
// some code omitted
}
Он просто переходит к свойству Control.WindowText
.Давайте проверим, что одно:
set
{
if (value == null) value = "";
if (!WindowText.Equals(value)) {
if (IsHandleCreated) {
UnsafeNativeMethods.SetWindowText(new HandleRef(window, Handle), value);
}
else {
if (value.Length == 0) {
text = null;
}
else {
text = value;
}
}
}
}
InvalidOperationException
исходит из метода получения свойства Handle
, который вызывается для получения экземпляра HandleRef
для вызова нативного метода.
get {
if (checkForIllegalCrossThreadCalls &&
!inCrossThreadSafeCall &&
InvokeRequired) {
throw new InvalidOperationException(SR.GetString(SR.IllegalCrossThreadCall, Name));
}
// further code omitted
}
Свойство Handle
будет доступно только тогда, когда IsHandleCreated
равно true
.В вашем случае вторая метка находится на элементе вкладки, дочерние элементы которого еще не отображаются, поэтому IsHandleCreated
для второй метки равно false
.Это означает, что свойство Handle
второй метки не доступно в потоке BackgroundWorker
.Вместо этого текстовое значение просто кэшируется в поле text
внутри элемента управления.Поэтому - не исключение.
Когда вы активируете второй элемент вкладки, создается дескриптор Label
, и код .NET Framework берет кэшированное текстовое значение из поля text
и применяет его кэтикетка.Это происходит в потоке пользовательского интерфейса, так что опять - никаких исключений.
Вы можете сначала переключиться на второй элемент вкладки и , а затем нажать вашу кнопку.Вы увидите исключение.Это связано с тем, что в этом случае дескриптор для второй метки будет уже создан.
Как общее примечание - никогда не следует обращаться к элементам пользовательского интерфейса из рабочих потоков, независимо от того, соблюдаете ли вы этиисключения или нет.Для всего взаимодействия с элементами пользовательского интерфейса из других потоков используйте синхронизацию: Control.Invoke
или Control.BeginInvoke
, SynchronizationContext
, TaskScheduler
и т. Д.