Form.InvokeRequired
возвращает false
до отображения формы.
Я сделал простой тест:
Form2 f2 = new Form2();
Thread t = new Thread(new ThreadStart(() => PrintInvokeRequired(f2)));
t.Start();
t.Join();
f2.Show();
t = new Thread(new ThreadStart(() => PrintInvokeRequired(f2)));
t.Start();
t.Join();
с помощником
private void PrintInvokeRequired(Form form)
{
Console.WriteLine("IsHandleCreated: " + form.IsHandleCreated + ", InvokeRequired: " + form.InvokeRequired);
}
вывод
IsHandleCreated: False, InvokeRequired: False
IsHandleCreated: True, InvokeRequired: True
Также обратите внимание, что это несколько документировано на MSDN :
Если дескриптор элемента управления еще не существует, InvokeRequired выполняет поиск в родительской цепочке элемента управления, пока не найдет элемент управления или форму, которая имеет дескриптор окна.Если не удается найти соответствующий дескриптор, метод InvokeRequired возвращает значение false.
Это означает, что InvokeRequired может возвращать значение false, если Invoke не требуется (вызов происходит в том же потоке), или если элемент управления был создан вдругой поток, но дескриптор элемента управления еще не создан.
В случае, когда дескриптор элемента управления еще не создан, вы не должны просто вызывать свойства, методы или события в элементе управления.Это может привести к созданию дескриптора элемента управления в фоновом потоке, изолируя элемент управления в потоке без насоса сообщений и делая приложение нестабильным.
Вы можете защитить от этого случая, также проверив значение IsHandleCreated, когдаInvokeRequired возвращает значение false в фоновом потоке.Если дескриптор элемента управления еще не создан, вы должны подождать, пока он не будет создан, прежде чем вызывать Invoke или BeginInvoke.Как правило, это происходит только в том случае, если фоновый поток создается в конструкторе первичной формы для приложения (как в Application.Run (new MainForm ()), до того, как форма была показана или был вызван Application.Run.
Ваше решение также состоит в том, чтобы проверить IsHandleCreated
.
Редактировать:
Handle
может быть создан в любое время внутри элемента управления WebBrowser.или внешне. Это не создает автоматически описатель родительской формы.
Я создал пример:
public Form2()
{
InitializeComponent();
Button button1 = new Button();
this.Controls.Add(button1);
Console.WriteLine("button1: " + button1.IsHandleCreated + " this: " + this.IsHandleCreated);
var tmp = button1.Handle; // Forces the Handle to be created.
Console.WriteLine("button1: " + button1.IsHandleCreated + " this: " + this.IsHandleCreated);
}
с выводом:
button1:False this: False
button1: True this: False