лекция надежность. А. ОсиповРазработка Windows приложенийна C#
Скачать 0.74 Mb.
|
BackgroundWorker и отслеживать события, сообщающие о ходе выполнения операции и сигнализирующие о ее завершении. Можно создать объект BackgroundWorker программными средствами или перетащить его в форму из вкладки Компоненты Панели элементов. Класс BackgroundWorker, созданный в конструкторе Windows Forms, появляется в области компонентов, а его свойства отображаются в окне "Свойства". Выполнив это упражнение, вы научитесь применять компонент BackgroundWorker. Вам предстоит добавить к приложению компонент BackgroundWorkerи написать отнимающий продолжительное время 44 метод, который будет выполняться в отдельном потоке. Затем вы сообщите о продвижении потока и реализуете функциональность отмены фонового процесса. 1. Создайте новый проект Windows Forms. Назовите его WinBackgroundWorker. 2. Добавьте на форму элементы управления: два элемента Label, TextBox, ProgressBar и две кнопки Button. 3. Для элементов укажите свойства в соответствии с таблицей: Элемент СвойствоЗначение Location 10;15 label1 Text Second to sleep Location 10; 40 label2 Text Progress Location 105; 13 textBox1 Size 80; 20 Location 110; 40 progressBar Size 240; 20 Location 195; 12 Text Start button1 Size 75; 25 Location 270; 12 Text Cancel button2 Size 75; 25 Form1 Size 370;110 4. Для элемента textBox1 допустимыми значениями будут только цифры, поэтому в обработчике события KeyPress для текстового поля textBox1 укажите код: if (!char.IsDigit(e.KeyChar)) { e.Handled = true; MessageBox.Show("Поле должно содержать цифры"); } 5. Из Toolbox перетащите элемент BackgroundWorkerв форму. 6. В окне Properties установите свойства WorkerSupportsCancellation и WorkerReportsProgressв True (для поддержки асинхронной отмены и возможности сообщения основному потоку информации о продвижении фонового процесса соответственно). 7. Дважды щелкните BackgroundWorker, чтобы открыть обработчик события backgroundWorker1_DoWorkпо умолчанию. Добавьте к этому обработчику события следующий код: int i; i = int.Parse(e.Argument.ToString()); for (int j=1; j <= i; j++) { if (backgroundWorker1.CancellationPending) 45 { e.Cancel = true; return; } System.Threading.Thread.Sleep(1000); backgroundWorker1.ReportProgress((int)(j *100/ i)); } 8. Для элемента backgroundWorkerl в окне Properties щелкните кнопку Events, затем дважды щелкните ProgressChanged, чтобы открыть окно кода обработчика события backgroundWorker1_ProgressChanged. Добавьте следующий код: progressBar1.Value = e.ProgressPercentage; 9. Аналогичным способом добавьте обработчик события RunWorkerCompleted, в теле обработчика добавьте следующий код: if (!(e.Cancelled)) System.Windows.Forms.MessageBox.Show("Run Completed!"); else System.Windows.Forms.MessageBox.Show("Run Cancelled"); 10. Для кнопки Start откройте обработчик события Click. Добавьте следующий код: if (!(textBox1.Text == "")) { int i = int.Parse(textBox1.Text); backgroundWorker1.RunWorkerAsync(i); } 11. Для кнопки Cancel откройте обработчик события Click. Добавьте следующий код backgroundWorker1.CancelAsync(); 12. Построите и выполните приложение, и проверьте его функциональность. Упражнение 2. Использованиеделегатов Выполнив это упражнение, вы создадите приложение, подобное тому, что было создано в упражнении 1. Оно будет выполнять продолжительную операцию в отдельном потоке с возможностью отмены, показывать продвижение операции и уведомлять пользователя о ее завершении. Для реализации этой функциональности вы используете делегаты и асинхронный вызов. 1. Создайте новое Windows-приложение и назовите его WinAsynchDelegate. 2. Повторите шаги 2 – 4 предыдущего упражнения для создания требуемой формы. 3. Добавьте в приложение следующий метод: private void TimeConsumingMethod(int seconds) { for (int j = 1; j <= seconds; j++) System.Threading.Thread.Sleep(1000); } 4. Используйте в приложении делегат, соответствующий методу TimeConsumingMethod: 46 private delegate void TimeConsumingMethodDelegate(int seconds); 5. Добавьте сообщающий о продвижении операции метод, который устанавливает значение элемента управления ProgressBar потокобезопасным способом, и делегата этого метода: public delegate void SetProgressDelegate(int val); public void SetProgress(int val) { if (progressBar1.InvokeRequired) { SetProgressDelegate del = new SetProgressDelegate(SetProgress); this.Invoke(del, new object[] { val }); } else { progressBar1.Value = val; } } 6. Для сообщения о продвижении операции добавьте следующую строку кода в цикл For метода TimeConsumingMethod: SetProgress((int)(j * 100) / seconds); 7. Добавьте в приложение логическую переменную с именем Cancel: bool Cancel; 8. Добавьте следующие строки кода в цикл For метода TimeConsumingMethod: if (Cancel) break; 9. Добавьте следующий код после цикла For метода TimeConsumingMethod: if (Cancel) { System.Windows.Forms.MessageBox.Show("Cancelled"); Cancel = false; } else { System.Windows.Forms.MessageBox.Show("Complete"); } 10. В конструкторе дважды щелкните кнопку GO!, чтобы открыть для нее обработчик события Click по умолчанию, и добавьте следующий код: TimeConsumingMethodDelegate del = new TimeConsumingMethodDelegate(TimeConsumingMethod); del.BeginInvoke(int.Parse(textBox1.Text), null, null); 11. В конструкторе дважды щелкните кнопку Cancel, чтобы открыть для нее обработчик события Click по умолчанию, и добавьте следующий код: Cancel = true; 12. Скомпилируйте и проверьте ваше приложение. 47 Упражнение 3. Асинхронныйзапускпроизвольногометода При разработке программного обеспечения наиболее часто требуется запускать асинхронно собственные методы. В .NET Framework можно асинхронно вызывать любой метод. Для этого необходимо определить делегат с той же сигнатурой, что и у вызываемого метода. Среда CLR автоматически определяет для этого делегата методы BeginInvoke и EndInvoke с соответствующими сигнатурами. Для асинхронного запуска нужно проделать следующие шаги: 1. Создать и запустить делегат с необходимой сигнатурой. После этого можно работать со своим методом так же, как и с методами со встроенной поддержкой асинхронной модели программирования. 2. Выбрать механизм оповещения о завершении и подготовить для него все необходимое. 3. Запустить метод асинхронно. 4. Получить результаты в основном потоке и обновить пользовательский интерфейс. Хотя компонент BackgroundWorkerобеспечивает удобный способ выполнения простых задач в фоновом потоке, иногда может потребоваться осуществить более тонкий контроль за фоновыми процессами. В этом упражнении вы научитесь асинхронно выполнять методы с использованием делегатов. 1. Создайте новое Windows-приложение и назовите его WinAsynchMethod. 2. Установите свойствам формы Size значение 425;200 и Text – "Асинхронный запуск". 3. Добавьте на форму три надписи, два текстовых поля и две кнопки, и установите им следующие свойства: Свойство Значение button1 Name btnRun Location 16; 64 Text Сумма button2 Name btnWork Location 120; 128 Text Работа label1 Name lblA Location 8; 24 Text Значение А label2 Name lblB Location 216; 24 Text Значение В 48 Свойство Значение textBox1 Name txbA Location 88; 24 Text textBox2 Name txbB Location 296; 24 Text 4. Создайте делегат: private delegate int AsyncSumm(int a, int b); 5. Создайте метод Summ, в котором будут складываться числа, вводимые в два текстовых поля, и укажите задержку операции на 9 секунд: private int Summ(int a, int b) { System.Threading.Thread.Sleep(9000); return a+b; } 6. Реализуйте обработчик кнопки btnRun, который будет включать также действия по организации асинхронного вызова: Создайте экземпляр делегата и проинициализируйте его методом Summ: AsyncSumm summdelegate = new AsyncSumm(Summ); Для использования механизма Сallback создайте экземпляр делегата AsyncCallBack: AsyncCallback cb = new AsyncCallback(CallBackMethod); После того как делегат инициализирован методом, можно запускать прикрепленный к делегату метод асинхронно с помощью метода BeginInvoke. Этот метод принимает две переменные типа int а и b, экземпляр cb делегата AsyncCallback и экземпляр summdelegate делегата SummDelegate: summdelegate.BeginInvoke(a, b, cb, summdelegate); 7. В итоге обработчик кнопки btnRun будет выглядеть следующим образом: private void btnRun_Click(object sender, System.EventArgs e) { int a, b; try { // Преобразование типов данных. a = Int32.Parse(txbA.Text); b = Int32.Parse(txbB.Text); } catch(Exception) { MessageBox.Show("При выполнении преобразования типов возникла ошибка"); txbA.Text = txbB.Text = ""; return; } 49 AsyncSumm summdelegate = new AsyncSumm(Summ); AsyncCallback cb = new AsyncCallback(CallBackMethod); summdelegate.BeginInvoke(a, b, cb, summdelegate); } 8. Создайте метод CallBackMethod, который привязан к делегату summdelegate: private void CallBackMethod(IAsyncResult ar) { string str; AsyncSumm summdelegate = (AsyncSumm)ar.AsyncState; str = String.Format("Сумма введенных чисел равна {0}", summdelegate.EndInvoke(ar)); MessageBox.Show(str, "Результат операции"); } 9. Для демонстрации асинхронности выполнения метода реализуйте обработчик нажатия кнопки Работа, например, следующим образом: MessageBox.Show("Работа кипит!!!"); 10. Постройте и запустите приложение. После нажатия кнопки Сумма, пока будет выполняться операция, нажмите кнопку Работа. Проверьте, что метод суммирования действительно реализован асинхронно. Лабораторнаяработа 8. Повышениеудобстваиспользования приложений Цельработы Изучение средств для повышения удобства работы пользователей и получение навыков по созданию контекстной справки, всплывающей подсказки, а также файлов со справочной информацией. Упражнение 1. Созданиеконтекстнойсправки Важной частью любого приложения является понятная и точная документация. Снабдить ваше приложение справкой позволяет компонент HelpProvider. 1. Откройте Windows-приложение WinAsynchMethod. 2. Откройте форму в режиме конструктора. 3. Выберите пункт меню ViewToolBox. 4. Добавьте ЭУ HelpProvider на форму. 5. Выделите поле txbA для отображения ее свойств. 6. Для свойства HelpString on helpProvider1 задайте значение For input integer A. 7. Постройте и запустите приложение. 8. Переместитесь по форме, используя клавишу Tab, до тех пор, пока поле txbA не окажется в фокусе. 9. Нажмите на клавишу F1 для отображения контекстной справки для поля txbA. 50 Простые формы обычно в своем заголовке имеют кнопку с вопросительным знаком, при нажатии на которую курсор меняет свой вид на изображение с вопросом. При щелчке на выбранном элементе управления появляется его краткое описание (подсказка). Создайте подобную функциональность на форме проекта WinAsynchMethod: 1. Добавьте к имеющимся свойствам формы следующие свойства: Свойство Значение MaximizeBox False MinimizeBox False HelpButton True FormBorderStyle FixedDialog 2. Для полей ввода txbA, txbB и двух кнопок в свойстве ShowHelp on helpProvider1 каждого из этих элементов установите значение True. 3. Текст, введенный в поле свойства HelpString on helpProvider1, будет появляться в качестве подсказки для конкретного элемента. Установите следующие значения этого свойства для каждого элемента: txbA For input integer A txbB For input integer B btnRun Sum btnWork Start work 4. Постройте и запустите приложение. 5. Для активации контекстной справки нажмите на кнопку “?”, расположенную в правом верхнем углу приложения. 6. Нажмите на любую кнопку, появится маленькое окошко, объясняющее, что происходит при ее нажатии. Упражнение 2. Использованиесправочногофайла 1. Откройте Windows-приложение WinAsynchMethod. 2. Откройте форму в режиме конструктора. 3. Выберите пункт меню ViewToolBox. 4. Добавьте ЭУ HelpProvider на форму (если он не был добавлен ранее). 5. В папке с решением создайте файл справки, например, документ Microsoft Word. Текст укажите произвольный. 6. Для элемента helpProvider1 в свойстве HelpNamespace укажите путь к файлу справки. 7. Реализуйте возможность вызова файла справки созданием либо команды меню, либо кнопки (и команда меню и кнопка может называться, например, help). 8. Создайте обработчик события выбора файла справки. В теле обработчика укажите следующую строку: Help.ShowHelp(this,helpProvider1.HelpNamespace); 51 9. Постройте и запустите приложение. 10. Выберите команду вызова справки. Проверьте, что открылся требуемый файл. Упражнение 3. Добавлениевсплывающихподсказок Компонент ToolTip позволяет назначить элементам управления подсказки. Они появляются в окнах, когда мышь находится над элементом управления, и могут предоставлять пользователю краткие сведения о нем. 1. Откройте Windows-приложение WinAsynchMethod в режиме конструктора. 2. Выберите пункт меню View ToolBox. 3. Добавьте на форму элемент управления ToolTip. 4. В окне Properties расположенных на форме элементов и в самой форме появилось свойство ToolTip on toolTip1. Установите следующие значения этого свойства для каждого из элементов: txbA For input integer A txbB For input integer B btnRun Sum btnWork Start work 5. Постройте и запустите приложение. Проверьте, что при наведении курсора на элемент управления появляется его подсказка. Упражнение 4. Автоматическийвыборязыкапризапускеприложения При распространении приложения часто бывает необходимо обеспечивать пользователям возможность работать в своей языковой среде. В связи с этим, при разработке приложений приходится задумываться о переводе пользовательского интерфейса на другие языки. На практике используется два способа решения данной проблемы, первый: создается локальная версия целиком на одном языке и второй: программы содержат многоязычный интерфейс, позволяющий менять оформление приложения непосредственно в ходе работы. В ходе установки операционной системы Windows при определении региональных параметров пользователю предлагается выбрать язык стандартов и форматов. Выбранное значение доступно для изменения в дальнейшем — меню “Пуск” | “Панель управления” | “Язык и региональные параметры” | вкладка “Региональные параметры”. В этом упражнении вы создадите приложение, которое автоматически будет определять установленный язык стандартов и выводить соответствующий пользовательский интерфейс. 1. Создайте новое Windows-приложение и назовите его WinLanguage. 2. Добавьте на форму кнопку и главное меню. 3. Установите следующие значения свойства Text для элементов: главное меню – menu, первая команда – command one, вторая команда – command two, 52 кнопка – Close, для самой формы – Form. 4. Для кнопки реализуйте обработчик, закрывающий форму: this.Close(); 5. Для формы установите свойству Localizable значение True. Это свойство разрешает поддержку многоязычного интерфейса. 6. В свойстве Language выберите значение English (United States). 7. Постройте приложение. В итоге получилась версия программы с интерфейсом на английском языке. 8. В свойстве Language выберите Russian (Russia). 9. Измените свойство Text элементов, заменив названия на английском языке соответствующими названиями на русском. 10. Перейдите в код формы и подключите пространство имен Threading: using System.Threading; 11. В конструкторе формы до InitializeComponent(); установите культуру пользовательского интерфейса равной текущей культуре: Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; 12. Постройте и запустите приложение. Среда CLR проверяет установленный язык и выводит приложение с интерфейсом на языке, установленном на вкладке "Региональные параметры" в настройках инструмента "Язык и региональные параметры". 13. Закройте приложение. Перейдите в "Панель управления" и установите другой язык (например, "Английский (США)") на вкладке "Региональные параметры" в настройках инструмента "Язык и региональные параметры". Снова запустите приложение. Теперь интерфейс приложения должен быть на другом языке (например, английском). 14. При локализации приложения среда Visual Studio .NET создает сборку, в которой хранятся все данные о приложении. В окне Solution Explorer нажмите на кнопку (Show All Files) для просмотра добавленных файлов. Названия файлов-ресурсов (Form1. en-US и Form1.ru-RU) содержат в себе указание на язык (первая часть – en или ru) и регион (вторая часть US или RU). Упражнение 5. Локализацияприложения Реализовать локализацию, т.е. предоставить пользовательский интерфейс, характерный для текущего региона, можно с помощью встроенных в Visual Studio средств локализации. Visual Studio позволяет создавать альтернативные версии культурозависимых форм и автоматически управляет поиском ресурсов, соответствующих данной культуре. Для пользовательского интерфейса культура предоставляется экземпляром CultureInfo и отличается от свойства 53 CulturInfo.CurrentCulture. В то время как оно определяет формат, применяемый к системно-форматируемым данным, CurrentUICulture определяет ресурсы, загружаемые в локализованные формы во время выполнения. Культура пользовательского интерфейса устанавливается в свойстве CurrentThread. CurrentUICulture В этом упражнении вы локализуете пользовательский интерфейс приложения и добавите в него локализованные строковые ресурсы. Локализацияформы |