if (box.InvokeRequired)
box.Invoke(new Action<string>(AddItem), new object[] { msg });
else
{
box.Items.Add(" " + msg);
box.SelectedIndex = box.Items.Count - 1;
}
}
public static void AddMsg(string msg)
{
ListBox box = form.listMsg;
if (box.InvokeRequired)
box.Invoke(new Action<string>(AddMsg), new object[] { msg });
else
{
box.Items.Add(" " + msg);
box.SelectedIndex = box.Items.Count - 1;
int val = form.progress.Value + 15;
if (val > 100)
val = 100;
form.progress.Value = val;
}
}
}
}
При открытии окна FormSplash мы пытаемся реализовать эффект постепенного проявления формы, а при закрытии — медленного ее затухания. Этот эффект достигается путем изменения свойства Opacity (степень непрозрачности) Windows-формы. Важным моментом при закрытии формы является немедленное обнуление объектов form и thread. Если отложить эти действия до момента завершения процесса затухания формы, то новый поток может вступить в конфликт со старым. Вы можете в этом убедиться самостоятельно, если перенесете код обнуления и выберете новый узел в дереве классов, не дожидаясь завершения процесса обработки события выбора старого.
При создании формы запускается таймер, который каждые 5 миллисекунд возбуждает событие Tick. В обработчике этого события изменяется степень непрозрачности формы (Opacity). Вызов CloseForm изменяет знак приращения Opacity и форма начинает затухать. В этот момент мы уже отдали ее на съедение сборщику мусора, но форма продолжает постепенно затухать, так как сборщик мусора не торопится выходить на работу. Стратегия сбора мусора достаточно сложна (см. http://ru.wikipedia.org/wiki/Сборка_мусора).
Для проверки работоспособности диалога FormSplash, уберите комментарий, блокирующий его создание и закрытие в методе QueryNamespaces класса WMIControl, удалите папку Data и запустите приложение.
Мы реализовали один из сценариев, в котором приложение демонстрирует пользователю свою занятость. Он обладает некоторыми достоинствами. Запустите приложение (удалив папку Data) и попробуйте в процессе поиска изменить положение движка полосы прокрутки списка listItem. Приложение позволяет это сделать, так как в нем существуют два цикла обработки событий. Найдите оба оператора, создающие эти циклы и создайте мысленную модель двух одновременно работающих приложений (интерфейсных потоков). Один из потоков связан с главным окном приложения, в то время, как splash-форма и связанное с ней приложение расположены в другом потоке.
Первичный поток приложения связан с главным окном приложения и компилятор не позволит добавить в этот поток еще один цикл обработки событий. Это возможно сделать только в другом потоке. Если убрать оператор Application.Run(form), создающий цикл обработки событий и работать с splash-формой обычным способом, то вы не сможете управлять полосой прокрутки списка в splash-форме.
Существует несколько способов создания дополнительных потоков в .NET Framework. Мы показали самый простой и прямой. Он состоит в том, что создается объект класса Thread и на вход его конструктора подается адрес метода, который должен выполняться в другом, параллельном потоке. Этим методом является StartApp, который запускает второй (интерфейсный) цикл обработки событий (см. код: Application.Run(form)).
Обратите внимание на то, что все методы класса (кроме его конструктора) статические. Сам конструктор стал скрытым (private). В классе появилась статическая ссылка на объект своего собственного класса.
static FormSplash form;
Это в корне меняет тактику работы с классом FormSplash в отличие от традиционного способа работы с диалоговыми формами. Благодаря наличию открытых статических методов в классе FormSplash, нам не нужно создавать объект класса FormSplash в классе WMIControl, так как он делает это сам (см. код метода StartApp).
Запустите приложение и убедитесь, что форма FormSplash (а по сути, параллельно работающее Application) позволяет управлять полосой прокрутки, строки списка появляются в моменты их создания и вы имеете возможность пошаговой отладки двух-поточного приложения. Напомню, что сам отладчик работает в другом (третьем) потоке.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.