У меня проблема с Control.BeginInvoke()
, которая не происходит каждый раз. Кажется, что он работает хорошо 5 раз или около того, а затем становится более успешным после 50/50.BeginInvoke() Call Delayed
Что происходит, так это то, что я назову BeginInvoke()
на элемент управления, который уже был создан и отображается, и вызов не будет выполняться в потоке графического интерфейса. Вызывающая нить делает немедленно возвращается с BeginInvoke()
и продолжает свою деятельность. Делегат не выполняется в потоке GUI до тех пор, пока на элементе управления не будет выполнено другое BeginInvoke()
. Тогда это похоже на то, что он понимает, что это что-то делать и, наконец, делает это. Это может быть более 10 минут спустя.
Код
Вот код, который выполняет BeginInvoke()
, которое не выполняет делегат сразу:
protected void DisplayPrompt(PromptData promptData)
{
Debug.WriteLine(DateTime.Now + ": Entering DisplayPrompt: " + Thread.CurrentThread.Name);
this.CurrentPrompt = promptData;
if (this.InvokeRequired)
{
Debug.WriteLine(DateTime.Now + ": Before BeginInvoke of DisplayPrompt: " + Thread.CurrentThread.Name);
this.BeginInvoke(new Action(() => this.DisplayPrompt(promptData)));
Debug.WriteLine(DateTime.Now + ": After BeginInvoke of DisplayPrompt: " + Thread.CurrentThread.Name);
return;
}
// The rest of the method goes here
}
Что кажется пинать вызывается метод через сообщение насос, когда код ниже выполняется. Этот код запускается после того, как я устал ждать выполнения вышеуказанного делегата, и я нажимаю кнопку, которая в конечном счете вызывает ClearPrompt()
.
protected void ClearPrompt()
{
Debug.WriteLine(DateTime.Now + ": Entering ClearPrompt: " + Thread.CurrentThread.Name);
this.CurrentPrompt = null;
if (this.InvokeRequired)
{
Debug.WriteLine(DateTime.Now + ": Before BeginInvoke of ClearPrompt: " + Thread.CurrentThread.Name);
this.BeginInvoke(new Action(() => this.ClearPrompt()));
Debug.WriteLine(DateTime.Now + ": After BeginInvoke of ClearPrompt: " + Thread.CurrentThread.Name);
return;
}
// The rest of the method goes here
}
И, наконец, вот выход:
11/13/2013 1:16:49 PM: Entering DisplayPrompt: BatchStateMachine
11/13/2013 1:16:49 PM: Before BeginInvoke of DisplayPrompt: BatchStateMachine
11/13/2013 1:16:49 PM: After BeginInvoke of DisplayPrompt: BatchStateMachine
The thread 0x998 has exited with code 0 (0x0).
The thread 0x1174 has exited with code 0 (0x0).
11/13/2013 1:27:01 PM: Entering ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: Before BeginInvoke of ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: After BeginInvoke of ClearPrompt: BatchStateMachine
11/13/2013 1:27:01 PM: Entering DisplayPrompt:
11/13/2013 1:27:01 PM: Entering ClearPrompt:
Это второй Entering DisplayPrompt
в 1:27:01 PM
именно там GUI, наконец, работает делегат.
Вопрос: Так что я думаю, вопрос в том, что может привести к BeginInvoke()
, чтобы это замедленное поведение, и что я могу сделать, чтобы лучше отладки этого?
Другие ноты:
- Эти методы относятся к экземпляру
UserControl
объекта - Объект
UserControl
существовавшего и отображается в течение нескольких минут до того, как код побежал, то есть ручки управления должен существовать. - Я использовал
BeginInvoke()
успешно так же, как это много раз до - GUI, похоже, полностью реагирует на время, в течение которого делегат должен быть запущен. Элементы управления графическим интерфейсом обновляются, я могу перемещаться по приложению и т. Д.
Спасибо!
Когда вы создаете что угодно, возможно, что к нему обратился фоновый поток до того, как он был создан на основном потоке случайно (или был создан в потоке, отличном от основного потока)? –
Вы имеете в виду, что он выполняется, но иногда откладывается или пропущен? –
@ScottChamberlain: я добавил точку останова для каждого открытого/защищенного элемента класса, и я вижу, что он создается и доступен только по основному потоку, прежде чем он будет отображаться. – user955629