Silverlight использует очередь рабочих элементов для обработки рендеринга и логики в потоке пользовательского интерфейса. Поскольку ваша логика также выполняется в потоке пользовательского интерфейса (в вашем обработчике button_Click
), средство визуализации не получает возможности рисовать экран до тех пор, пока не завершится выполнение вашего метода И внутренний цикл обработки сообщений не дойдет до рисования экрана.
Ваш BeginInvoke
немедленно помещает вашу функцию в рабочую очередь Silverlight для выполнения в потоке пользовательского интерфейса (и немедленно возвращается). Порядок Silverlight обрабатывает это, вероятно, что-то вроде:
- Пользователь нажимает кнопку, помещая событие щелчка в рабочую очередь
- Silverlight видит событие click и вызывает
button_Click
(который помещает новое действие в рабочую очередь)
- Обрабатывает следующий элемент рабочей очереди, который, вероятно, является вашим
Thread.Sleep
действием, останавливая поток пользовательского интерфейса на 5 секунд
- Наконец Silverlight начинает рисовать на экране
То, что вы хотите сделать, - это создать новый поток для выполнения вашей работы, а затем BeginInvoke
вернуться в поток пользовательского интерфейса:
var thread = new Thread(() => {
Thread.Sleep(5000);
Dispatcher.BeginInvoke(() => {
// update UI
textBox.Text = "2";
});
});
textBox.Text = "1";
thread.Start();
Я должен добавить, что Silverlight 5 добавляет поток композиции, который может выполнять определенные действия для обновления пользовательского интерфейса, не блокируя поток пользовательского интерфейса, такой как воспроизведение анимации и выполнение ускоренного рендеринга на GPU, где это возможно.