авторефераты диссертаций БЕСПЛАТНАЯ БИБЛИОТЕКА РОССИИ

КОНФЕРЕНЦИИ, КНИГИ, ПОСОБИЯ, НАУЧНЫЕ ИЗДАНИЯ

<< ГЛАВНАЯ
АГРОИНЖЕНЕРИЯ
АСТРОНОМИЯ
БЕЗОПАСНОСТЬ
БИОЛОГИЯ
ЗЕМЛЯ
ИНФОРМАТИКА
ИСКУССТВОВЕДЕНИЕ
ИСТОРИЯ
КУЛЬТУРОЛОГИЯ
МАШИНОСТРОЕНИЕ
МЕДИЦИНА
МЕТАЛЛУРГИЯ
МЕХАНИКА
ПЕДАГОГИКА
ПОЛИТИКА
ПРИБОРОСТРОЕНИЕ
ПРОДОВОЛЬСТВИЕ
ПСИХОЛОГИЯ
РАДИОТЕХНИКА
СЕЛЬСКОЕ ХОЗЯЙСТВО
СОЦИОЛОГИЯ
СТРОИТЕЛЬСТВО
ТЕХНИЧЕСКИЕ НАУКИ
ТРАНСПОРТ
ФАРМАЦЕВТИКА
ФИЗИКА
ФИЗИОЛОГИЯ
ФИЛОЛОГИЯ
ФИЛОСОФИЯ
ХИМИЯ
ЭКОНОМИКА
ЭЛЕКТРОТЕХНИКА
ЭНЕРГЕТИКА
ЮРИСПРУДЕНЦИЯ
ЯЗЫКОЗНАНИЕ
РАЗНОЕ
КОНТАКТЫ


Pages:     | 1 |   ...   | 2 | 3 || 5 |

«УДК 002.52/.54(075.8) ББК 32.81я73 МИНОБРНАУКИ РОССИИ ...»

-- [ Страница 4 ] --

Константы в C# - это члены класса, значения которых определены в течение всего выполнения программы и определяются еще на этапе компиляции. Определение константы производится посредством ключевого слова const:

const int a = 2;

Константы не могут определяться со словом static, но в то же время являются членами класса, а не экземпляра. Константы могут быть инициализированы как прямо конкретными значениями, так и через другие константы:

const int a = 3;

const int b = a + 7;

Управляющие конструкции Управляющие конструкции - это то средство, которое позволяет вам создавать алгоритмы. Стандартными управляющими конструкциями являются if, for, while goto.

К тому же в C# есть много дополнительных конструкций: switch, do и foreach.

if..else Блок if..else, как видно из названия, позволяет выполнять код при выполнении определенного условия.

if (a b) { Console.WriteLine("a b");

} else { Console.WriteLine("a = b");

} Логическое выражение в скобках должно иметь тип bool (в отличие от C/C++, где выражение было целым). Если оно истинно, выполнится первый блок команд, если ложно - второй. При этом если какой-либо блок команд состоит лишь из одной команды, обрамляющие фигурные скобки можно опустить (!= означает неравенство, т.е. ! означает логическое «не»):

if (serverObject != null) serverObject.Initialize();

Покажем несколько примеров:

// Идет проверка, чтобы избежать деления на if (x != 0) { d /= x;

} else return;

// Проверяем, вернула ли процедура значение и, если нет, возвращаем null if (command.Parameters["RETURN_VALUE"].Value != Convert.DBNull) return command.Parameters["RETURN_VALUE"].Value;

else return null;

Цикл for Цикл for представляет цикл с инициализирующей командой, условием окончания и командой перехода.

ArrayList items = new ArrayList();

// Инициализируем список некоторым образом CreateArray(items);

// Выводим все его элементы по очереди for (int i = 0;

i items.Count;

i++) { Console.WriteLine("i[{0}] = {1}", i, items[i]);

} Логика выполнения цикла следующая: сначала выполняется инициализирующая команда, далее идет шаг цикла: проверяется условие окончания, если оно ложно, то цикл прекращается и управление переходит на следующую за циклом команду, иначе выполняется тело цикла, а после него - команда перехода.

В простейшем случае цикл for оформлен следующим образом:

// Складываем все элементы массива for (int i = 0;

i 10;

i++) sum += array[i];

Такая форма цикла используется, если вам нужно проитерироваться с целым параметром, указывающим номер итерации или если просто нужно выполнить действие некоторое количество (в нашем примере 10) раз.

while Цикл while является циклом с предусловием: сначала проверяется определенное условие перехода, а затем выполняется итерация цикла. Синтаксис цикла while в общем случае следующий:

// Задаем число int num = 678;

// Число разрядов - int len = 0;

// считаем сколько разрядов в числе while (num 0) { len++;

num /= 10;

} Console.WriteLine(len);

Семантика очень проста: проверяем условие перехода. Если оно истинно, то переходим к телу цикла и затем снова к проверке условия, иначе - прекращаем выполнение цикла. В качестве дополнительного примера опять сошлемся на ADO.NET - чтение данных посредством SqlReader:

// Есть ли еще данные в result set? Если есть, читаем их while (reader.Read()) { // Обрабатываем данные users.Add(new User((int)reader["ID"]);

} goto goto - это просто оператор безусловного перехода. Он применяется в двух ситуациях: когда нужно перейти на обработку определенного случая в блоке switch (он будет рассмотрен позднее) или выполнить переход в определенное место программы. Во втором случае нужно указать метку в этом месте. Метка указывается просто - в нужном месте программы пишется имя метки с двоеточием на конце:

Exit: return 0;

Чтобы перейти на эту метку, используется следующий синтаксис оператора goto:

goto Exit;

Еще goto применяется если нужно перейти к определенной ветви в блоке switch:

int level = GetLevel();

switch (level) { case 0:

Console.WriteLine("Level is less than 1");

break;

case 1:

goto case 2;

case 2:

Console.WriteLine("level is greater than or equal to 1");

goto default;

default:

Console.WriteLine("bye");

break;

} switch Оператор switch является расширенным оператором ветвления, который позволяет в зависимости от значения выражения перейти к выполнению определенного кода. По сути, он эквивалентен набору блоков if, но оптимальнее, так как в нем для вычисления адреса перехода используется хеш. Наиболее распространенным синтаксисом switch является следующий:

int a = 1;

switch (a) { case 0:

//Операторы, выполняющиеся если a = Console.WriteLine("A = 0");

break;

case 1:

//Операторы, выполняющиеся если a = Console.WriteLine("A = 1");

break;

default:

//Операторы, выполняющиеся, если ни один из явных случаев не подошел Console.WriteLine("A 0 и A 1");

break;

} Блок case x выполняется, если выражение, указанное в скобках после switch равно x. Блок default - если ни одно из case-выражений не выполнилось. Удобно switch использовать для обработки выражений перечислимых типов. Для переходов между блоками можно использовать команды goto case и goto default. Для подробной информации смотрите описание оператора goto.

do Оператор do реализует цикл с постусловием. Суть этого цикла аналогична while, но условие выхода проверяется не до итерации, а после. Это иногда бывает удобным.

string s = "A, B, C, D";

do { s = s.Substring(s.IndexOf(",") + 1);

} while (s.Length 0);

Обычно его используют, когда проверку нужно выполнить после того, как прошла хотя бы одна итерация.

foreach foreach - это очень удобный оператор, значительно облегчающий работу с коллекциями в C#.

Он позволяет перебрать все элементы некоторой коллекции, даже написанной вами, для этого класс коллекции должен лишь реализовать интерфейс IEnumerable.

Наиболее общей формой использования foreach является следующая:

// Получаем некоторый DataSet DataSet data = GetData();

foreach (Row row in data.Tables[0].Rows) { Console.WriteLine("ID = {0}", row["ID"]);

} Оператор перебирает все элементы коллекции и выполняет для каждого тело перечислителя.

Выполнение задания:

1. Локальные переменные – это переменные, объявленные в теле метода. Они не инициализируются автоматически, и время их жизни зависит от компилятора, но оно не больше, чем время исполнения метода.

Локальные переменные могут быть определены и в управляющих блоках for, while, foreach, if.

using System;

namespace LocalVariables { public class Application { static int i = 117;

// - глобальная переменная i public static void Main() { for (int i = 0;

i 10;

i++) // - локальная переменная i { Console.WriteLine("i = {0}", i);

// - вывод номера итерации } Console.WriteLine("i = {0}", Application.i);

// - вывод значение глобальной переменной } } } Вывод программы следующий:

i = i = i = i = i = i = i = i = i = i = i = Самостоятельная работа:

1. Разработать прикладной циклический алгоритм по собственной тематике.

2. Выполнить отладку и тестирование разработанного прикладного алгоритма.

3. Документировать результаты работы.

Ответить на вопросы:

1. Какие методы использует консольное приложение.

2. Какие особенности обработки данных существуют в C#.

3. Как выполняется отладка и тестирование прикладного алгоритма.

4. Какие требования к надежности прикладных алгоритмов предъявляются в среде Visual Studio.Net.

5. Какие структуры данных использованы в вашем разработанном прикладном алгоритме.

Лабораторная работа № 5. Современные подходы к производству и обработке информации Цель: Изучение возможностей проектирования и разработки параллельных алгоритмов.

Оценка сложности программ.

Задачи: Изучение особенностей работы с параллельными алгоритмами. Изучение принципов обработки потоков данных. Организация прикладных алгоритмов многопоточности на языке C#. Обработка событий. Создание многопоточных приложений в среде Visual Studio.Net.

Формируемые компетенции:

- навыки обработки сложных параллельных алгоритмов современными методами и средствами;

- навыки обработки потоков информации;

- навыки одновременной визуализации параллельных процессов для отслеживания их качества;

- навыки функционального программирования на языке C#;

- навыки тестирования и отладки, документирования и сопровождения программного обеспечения в современных средах программирования.

Задание:

1. Изучить теоретические основы обработки параллельных алгоритмов.

2. Разобрать особенности и технологию обработки параллельных алгоритмов на языке программирования C#.

3. Разработать приложение для пользователя (проект), в котором реализовать прикладной алгоритм параллельной обработки потоков информации.

4. Визуализировать процесс контроля работы с потоками информации.

5. Применить различные методы сортировки для обработки потоков информации.

Теория Процесс, поток, домен.

Процесс - объект, который создаётся Операционной Системой для каждого приложения в момент его запуска. Характеризуется собственным адресным пространством, которое напрямую недоступно другим процессам.

Поток. В рамках процесса создаются потоки (один - первичный создаётся всегда). Это последовательность выполняемых команд процессора. В приложении может быть несколько потоков (первичный поток и дополнительные потоки).

Потоки в процессе разделяют совместно используемые данные и имеют собственные стеки вызовов и локальную память потока (Thread Local Storage -TLS).

Главное - это то, что все потоки выполняются в рамках общего адресного пространства (в рамках одного процесса). Нет ничего, кроме выполняющихся потоков, которыми руководит управляющий поток ОС. Взаимодействие между одними потоками проще, если эти потоки выполняются в рамках одного процесса. При этом всё равно требуется специальный инструментарий (критические секции, мьютексы и семафоры) и остаётся множество проблем, решение которых требует внимания со стороны программиста.

Для обеспечения взаимодействия потоков в разных процессах используются каналы, обмен информацией через которые обеспечивается специальными системными средствами. Общее управление выполнением потоков осуществляется на уровне ОС (рис.1).

Рис.1 – Выполнение потоков в операционной системе Домен приложения. Выполнение приложений.NET всегда начинается с запуска.NET Framework. Это процесс со своими потоками, специальными атрибутами и правилами взаимодействия с другими процессами. Домены приложения одного процесса не могут совместно использовать никакие данные за исключением случаев, когда используется протокол удалённого доступа к данным.NET.

В одном процессе могут выполняться множества доменов приложений. При этом в рамках одного домена может выполняться множество потоков (таблица 1).

Таблица 1 – Методы обработки процессов Методы класса System.AppDomain Описание CreateDomain() Статический. Создает новый экземпляр домена GetCurrentThreadId() Статический. Возвращает Id текущего потока.

Unload() Статический. Для выгрузки из процесса указанного домена приложения.

BaseDirectory Свойство. Возвращает базовый каталог, который используется распознавателем для поиска нужных приложению сборок.

CreateInstance() Overloaded. Creates a new instance of a specified type defined in a specified assembly.

ExecuteAssembly() Запускает на выполнение сборку, имя которой было указано в качестве параметра.

GetAssemblies() Возвращает список сборок, загруженных в текущий домен приложения.

Load() Загружает сборку в текущий домен приложения.

В рамках обычного (Win32) процесса может быть создано множество доменов.

Причём новые домены можно создавать непосредственно в ходе выполнения.NET Порождение новых доменов обеспечивается четвёркой статических перегруженных методов членов класса AppDomain с именем CreateDomain.

Обзор пространства имён System.Threading. В этом пространстве объявляются типы, которые используются для создания многопоточных приложений: работа с потоком, средства синхронизации доступа к общим данным, примитивный вариант класса Timer ( таблица 2).

Таблица 2 – Типы многопоточных приложений Тип Назначение Interlocked Синхронизация доступа к общим данным.

Monitor Синхронизация потоковых объектов при помощи блокировок и управления ожиданием.

Mutex Синхронизация процессов.

Thread Собственно класс потока, работающего в среде выполнения.NET. В текущем домене приложения с помощью этого класса создаются новые потоки.

ThreadPool Класс, предоставляющий средства управления набором взаимосвязанных потоков.

ThreadStart Класс-делегат для метода, который должен быть выполнен перед запуском потока.

Timer Вариант класса-делегата, который обеспечивает передачу управления некоторой функции-члену (неважно какого класса!) в указанное время. Сама процедура ожидания выполняется потоком в пуле потоков.

TimerCallback Класс-делегат для объектов класса Timer.

WaitHandle Объекты-представители этого класса являются объектами синхронизации (обеспечивают многократное ожидание).

WaitCallback Делегат, представляющий методы для рабочих элементов (объектов) класса ThreadPool Многопоточность. Многопоточная ОС. Прежде всего, операционная система должна допускать параллельную (псевдопараллельную) работу нескольких программ.

Многопоточное приложение: отдельные компоненты работают одновременно (псевдо одновременно), не мешая друг другу. Случаи использования многопоточности: выполнение длительных процедур, ходом выполнения которых надо управлять, функциональное разделение программного кода: пользовательский интерфейс - функции обработки информации, обращение к серверам и службам Инернета, базам данных, передача данных по сети, одновременное выполнение нескольких задач, имеющих различный приоритет.

Виды многопоточности Переключательная многопоточность. Основа - резидентные программы.

Программа размещалась в памяти компьютера вплоть до перезагрузки системы.

Управление ей передавалось каким-либо заранее согласованным способом (предопределённой комбинацией клавиш на клавиатуре).

Совместная многопоточность. Передача управления от одной программы другой.

При этом возвращение управления - это проблема выполняемой программы. Возможность блокировки, при которой аварийно завершаются ВСЕ программы.

Вытесняющая многопоточность. ОС централизованно выделяет всем запущенным приложениям определённый квант времени для выполнения в соответствии с приоритетом приложения. Реальная возможность работы нескольких приложений в псевдопараллельном режиме. "Зависание" одного приложения не является крахом для всей системы и оставшихся приложений.

Класс Thread. Общая характеристика Thread класс представляет управляемые потоки. Создаёт потоки и управляет ими:

устанавливает приоритет и статус потоков. Это объектная оболочка вокруг определённого этапа выполнения программы внутри домена приложения (таблица 3).

Таблица 3 – Описание класс представления потоков Статические члены Назначение класса Thread CurrentThread Свойство. Только для чтения. Возвращает ссылку на поток, выполняемый в настоящее время.

GetData() Обслуживание слота текущего потока.

SetData() GetDomain() Получение ссылки на домен приложения (на ID домена), в GetDomainID() рамках которого работает указанный поток.

Sleep() Блокировка выполнения потока на определенное время.

Нестатические члены Назначение IsAlive Свойство. Если поток запущен, то true IsBackground Свойство. Работа в фоновом режиме. GC работает как фоновый поток.

Name Свойство. Дружественное текстовое имя потока. Если поток никак не назван - значение свойства установлено в null. Поток может быть поименован единожды. Попытка переименования потока возбуждает исключение.

Priority Свойство. Значение приоритета потока. Область значений значения перечисления ThreadPriority.

ThreadState Свойство. Состояние потока. Область значений - значения перечисления ThreadState.

Interrupt() Прерывание работы текущего потока.

Join() Ожидание появления другого потока (или определённого промежутка времени) с последующим завершением.

Resume() Возобновление выполнения потока после приостановки.

Start() Начало выполнения ранее созданного потока, представленного делегатом класса ThreadStart.

Suspend() Приостановка выполнения потока.

Abort() Завершение выполнения потока посредством генерации исключения TreadAbortException в останавливаемом потоке. Это исключение следует перехватывать для продолжения выполнения оставшихся потоков приложения. Перегруженный вариант метода содержит параметр типа object. An object that contains application specific information, such as state, which can be used by the thread being aborted.

Одной из очень важных особенностей языка C# является то, что он имеет встроенную поддержку многопоточного программирования. Особенность многопоточной программы является то, что она может состоять из нескольких частей, каждая из которых выполняет свою часть поставленной задачи. Таким образом, части выполняются параллельно. Такая часть программы называется потоком. Среда.NET Framework, в свою очередь, содержит ряд классов, предназначенный для гибкой реализации многопоточных приложений. Причем, в отличие от других языков программирования, имевших слабые места или подводные камни, встречавшиеся в процессе создания многопоточных приложений, C#, в силу своей встроенной поддержки многопоточности, позволяет полностью ликвидировать эти проблемы, или, в худшем случае, свести их к минимуму.

Поток (по-английски - это thread, буквально можно перевести как «нить») – это управляемая единица кода, выполняемая в адресном пространстве породившего его потока.

Используя многопоточность, мы можем реализовать нашу программу таким образом, что бы один поток просчитывал графику в сцене, визуализировал ее и обновлял окно, а другой, в это же самое время просчитывал физические законы, которые происходят в сцене. Потоки могут выполняться, ожидать выполнения, быть временно приостановленными (после чего возобновленными), заблокированными. Так же поток может просто завершиться. Все это – возможные состояния потока. Многопоточность в среде.NET Framework реализована следующим образом: существуют два типа потоков: высокоприоритетный и низкоприоритетный. Высокоприоритетный(foreground) поток в отличии от низкоприоритетного (или фонового - background), назначается, как тип потока по умолчанию, а так же не будет остановлен, в том случае, если все высокоприоритетные потоки к его процессе будут остановлены. В C#, классы, отвечающие за поддержку многопоточного программирования, определены в пространстве имен System.Threading.

Выполнение задания. При старте программы запустить на выполнение 4 потока, каждый из которых будет выводить сортировку массива. При создании потоков необходимо установить для них различные приоритеты, таким образом, чтобы для некоторых потоков выделялось больше квантов времени процессора, и они доминировали при выполнении сортировки.

1. Создайте новый проект.

В появившемся окне выбираем тип проекта (рис.2) и задаем ему имя.

Рис.2 – Окно создания нового проекта 2. На главной форме должны находиться следующие компоненты:

- Panel (4 шт). Для графического отображения сортируемого массива. Расположить 4 панели рядом с друг другом. Задать размер (100х200).

- ComboBox (4 шт). Для выбора приоритета потока. Разместить ComboBox’ы соответственно под панелями и внести в них следующий список, в строгом порядке: Низший, Ниже среднего, Средний, Выше среднего, Самый высокий.

- Button (2 шт). Одна кнопка предназначена для запуска потоков, другая – для сброса отсортированных массивов.

В целом дизайн формы должен выглядеть так (рис.3):

Рис.3 – Макет формы приложения 3. В тексте программы необходимо создать экземпляры 4-х массивов:

const int ncount = 200;

//количество элементов в массиве (высота панели) int[] array1 = new int[ncount];

//сортируемый массив int[] array2 = new int[ncount];

//сортируемый массив int[] array3 = new int[ncount];

//сортируемый массив int[] array4 = new int[ncount];

//сортируемый массив Создать функцию первичного заполнения массива случайными числами:

//первоначальное заполнение массива void InitArray() { Random r = new Random();

for (int i = 0;

i ncount;

i++) { array1[i] = r.Next(0, 100);

array2[i] = array1[i];

array3[i] = array1[i];

array4[i] = array1[i];

} } Создать функцию сортировки массива и отображения хода сортировки на панели:

//Сортировка массива и вывод результатов на экран static void SortArray(object _Params)//(int[] a, IntPtr p)//Panel p) { //связываем переменную g с графическим контекстом панели на форме int[] a = (int[])((Array)_Params).GetValue(0);

IntPtr p = (IntPtr)((Array)_Params).GetValue(1);

Color bkcolor = (Color)((Array)_Params).GetValue(2);

int panel_width = (int)((Array)_Params).GetValue(3);

Graphics g = Graphics.FromHwnd(p);

//.Handle);

for (int i = 0;

i ncount;

i++) { for (int j = i;

j ncount;

j++) if (a[i] a[j]) { //меняем местами меньший и больший элемент массива int tmp = a[i];

a[i] = a[j];

a[j] = tmp;

g.DrawLine(new Pen(bkcolor), 0, j, panel_width, j);

//стираем линию g.DrawLine(new Pen(Color.Navy), 0, j, a[j], j);

//рисуем линию g.DrawLine(new Pen(bkcolor), 0, i, panel_width, i);

//стираем линию g.DrawLine(new Pen(Color.Navy), 0, i, a[i], i);

//рисуем линию } } } Создать функцию перерисовки панели:

//Вывод массива на панель void DrawArrayIntoPanel(int[] a, Panel p) { Graphics g = Graphics.FromHwnd(p.Handle);

for (int i = 0;

i ncount;

i++) { g.DrawLine(new Pen(p.BackColor), 0, i, p.Width, i);

g.DrawLine(new Pen(Color.Navy), 0, i, a[i], i);

} } 4. Привязать созданные функции к элементам пользовательского интерфейса, согласно их назначению. В целом программа будет выглядеть следующим образом:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.Threading;

namespace SampleThread { public partial class Form1 : Form { public Form1() { InitializeComponent();

} const int ncount = 200;

//количество элементов в массиве (высота панели) int[] array1 = new int[ncount];

//сортируемый массив int[] array2 = new int[ncount];

//сортируемый массив int[] array3 = new int[ncount];

//сортируемый массив int[] array4 = new int[ncount];

//сортируемый массив //первоначальное заполнение массива void InitArray() { Random r = new Random();

for (int i = 0;

i ncount;

i++) { array1[i] = r.Next(0, 100);

array2[i] = array1[i];

array3[i] = array1[i];

array4[i] = array1[i];

} } //Вывод массива на панель void DrawArrayIntoPanel(int[] a, Panel p) { Graphics g = Graphics.FromHwnd(p.Handle);

for (int i = 0;

i ncount;

i++) { g.DrawLine(new Pen(p.BackColor), 0, i, p.Width, i);

g.DrawLine(new Pen(Color.Navy), 0, i, a[i], i);

} } //Сортировка массива и вывод результатов на экран static void SortArray(object _Params)//(int[] a, IntPtr p)//Panel p) { //связываем переменную g с графическим контекстом панели на форме int[] a = (int[])((Array)_Params).GetValue(0);

IntPtr p = (IntPtr)((Array)_Params).GetValue(1);

Color bkcolor = (Color)((Array)_Params).GetValue(2);

int panel_width = (int)((Array)_Params).GetValue(3);

Graphics g = Graphics.FromHwnd(p);

//.Handle);

for (int i = 0;

i ncount;

i++) { for (int j = i;

j ncount;

j++) if (a[i] a[j]) { //меняем местами меньший и больший элемент массива int tmp = a[i];

a[i] = a[j];

a[j] = tmp;

g.DrawLine(new Pen(bkcolor), 0, j, panel_width, j);

//стираем линию g.DrawLine(new Pen(Color.Navy), 0, j, a[j], j);

//рисуем линию g.DrawLine(new Pen(bkcolor), 0, i, panel_width, i);

//стираем линию g.DrawLine(new Pen(Color.Navy), 0, i, a[i], i);

//рисуем линию } } } private void button1_Click(object sender, EventArgs e) { Thread th_1 = new Thread(SortArray);

Thread th_2 = new Thread(SortArray);

Thread th_3 = new Thread(SortArray);

Thread th_4 = new Thread(SortArray);

th_1.Priority = (ThreadPriority)comboBox1.SelectedIndex;

th_2.Priority = (ThreadPriority)comboBox2.SelectedIndex;

th_3.Priority = (ThreadPriority)comboBox3.SelectedIndex;

th_4.Priority = (ThreadPriority)comboBox4.SelectedIndex;

object[] ps1 = { array1, panel1.Handle, panel1.BackColor, panel1.Width };

object[] ps2 = { array2, panel2.Handle, panel2.BackColor, panel2.Width };

object[] ps3 = { array3, panel3.Handle, panel3.BackColor, panel3.Width };

object[] ps4 = { array4, panel4.Handle, panel4.BackColor, panel4.Width };

th_1.Start(ps1);

th_2.Start(ps2);

th_3.Start(ps3);

th_4.Start(ps4);

th_1.Join();

th_2.Join();

th_3.Join();

th_4.Join();

} private void Form1_Load(object sender, EventArgs e) { InitArray();

comboBox1.SelectedIndex = 0;

comboBox2.SelectedIndex = 1;

comboBox3.SelectedIndex = 2;

comboBox4.SelectedIndex = 3;

} private void button2_Click(object sender, EventArgs e) { InitArray();

panel1.Refresh();

panel2.Refresh();

panel3.Refresh();

panel4.Refresh();

} private void panel1_Paint(object sender, PaintEventArgs e) { DrawArrayIntoPanel(array1, panel1);

} private void panel2_Paint(object sender, PaintEventArgs e) { DrawArrayIntoPanel(array2, panel2);

} private void panel3_Paint(object sender, PaintEventArgs e) { DrawArrayIntoPanel(array3, panel3);

} private void panel4_Paint(object sender, PaintEventArgs e) { DrawArrayIntoPanel(array4, panel4);

} } } 5. Запустить программу на выполнение. Формируем требования к результату выполнения.

Задаем приоритеты (рис.4). Затем задаем различные приоритеты потоков. Нажать кнопку «Сортировать».

Рис.4 – Установка приоритетов выполнения Результат параллельного выполнения сортировки показан ниже (рис.5):

Рис.5 – Результат выполнения прикладного алгоритма Самостоятельная работа:

1. Разработать прикладной алгоритм, в котором реализовать контроль над четырьмя методами различной сортировки.

2. Оценить сложность выполнения алгоритма.

3. Выполнить сравнительный анализ методов сортировки.

4. Выполнить сравнительный анализ обработки параллельных процессов.

5. Выполнить документирование прикладного алгоритма.

Ответить на вопросы:

1. Что такое поток?

2. Что такое процесс?

3. Как обрабатываются многопоточные алгоритмы с помощью языка программирования C#?

4. Как оценить сложность прикладного алгоритма?

5. Каковы особенности обработки параллельных алгоритмов современными технологиями программирования.

Лабораторная работа № 6. Современные технологии программирования Цель: Изучение технологии виртуального и объектно-ориентированного программирования.

Изучение механизма передачи данных из внешней среды в среду visual Studio.Net Задачи:

1. Повторить теоретические основы и акцентировать внимание на механизме работы с внешними источниками данных.

2. Рассмотреть основные теоретические особенности среды и языка программирования C# для обработки структурированных данных.

3. Разработать проект, в котором разработан механизм выбора данных из внешнего источника данных. Изучить особенности ADO.

4. Реализовать проект. Выполнить отладку и тестирование на реальных данных.

5. Оценить надежность и эффективность функционирования проекта.

Формируемые компетенции:

- навыки обработки данных из внешних источников баз данных;

- навыки работы с ADO;

- навыки разработки проектов, в которых реализован прикладной алгоритм для конкретной предметной области;

- навыки отладки и тестирования прикладных алгоритмов;

- навыки документирования прикладного алгоритма;

Задание:

1. Описать структуры данных и разработать базу данных в предметной области.

2. Разработать прикладной алгоритм, использующий механизм ADO для связывания удаленных данных.

3. Оценить качество и надежность работы приложения.

Теория Реляционные базы данных. Основные понятия Детали реализации конкретной базы данных в рамках данной СУБД не обсуждаются..NET для того и используется, чтобы максимально скрыть детали реализации конкретной базы и предоставить программисту набор стандартных классов, интерфейсов, программных средств, которые превращают процесс создания приложения в стандартизированный технологический процесс. Таким образом, с точки зрения.NET:

столбец (поле, атрибут) — • характеризуется определенным типом (данных), • множество значений столбца являются значениями одного типа;

строка (запись, кортеж) — • характеризуется кортежем атрибутов, • состоит из упорядоченного множества значений (кортежа) атрибутов;

таблица — • набор данных, представляющих объекты определенного типа, • состоит из множества элементов столбцов-строк, • каждая строка таблицы уникальна;

первичный ключ таблицы — • непустое множество столбцов таблицы (возможно, состоящее из одного столбца), соответствующие значения (комбинации значений) которых в строках таблицы обеспечивают уникальность каждой строки в данной таблице;

внешний ключ таблицы — • непустое множество столбцов таблицы (возможно, состоящее из одного столбца), соответствующие значения (комбинации значений) которых в строках таблицы соответствуют первичному или дополнительному ключу другой таблицы, • обеспечивает логическую связь между таблицами.

Работа с базами данных Работа с БД на уровне приложения.NET – это работа:

•с множествами объявлений классов, которые содержат объявления унаследованных методов и свойств, предназначенных для решения задачи извлечения информации из базы данных;

• с множеством объектов-представителей классов, которые обеспечивают работу с базами данных;

• с множеством значений и свойств конкретных объектов, отражающих специфику структуры конкретной базы данных.

Функциональные особенности этой сложной системы взаимодействующих классов обеспечивают единообразную работу с базами данных независимо от системы управления базой и ее реализации. Для программиста – разработчика приложения принципиальной становится информация о логической организации (структуре таблиц, отношениях и ограничениях) данной конкретной базы данных — то есть о том, как эту базу видит приложение. Потому, желательно: понимать принципы организации и взаимодействия классов, которые обеспечивают работу с базой данных;

представлять структуру, назначение и принципы работы соответствующих объектов;

знать, для чего и как применять различные детали при организации взаимодействия с базами данных;

Есть четыре основных типа запросов данных в SQL, которые относятся к так называемому языку манипулирования данными (Data Manipulation Language или DML):

• SELECT – выбрать строки из таблиц;

• INSERT – добавить строки в таблицу;

• UPDATE – изменить строки в таблице;

• DELETE – удалить строки в таблице;

Каждый из этих запросов имеет различные операторы и функции, которые используются для того, чтобы произвести какие-то действия с данными. Запрос SELECT имеет самое большое количество опций. Существуют также дополнительные типы запросов, используемых вместе с SELECT, типа JOIN и UNION. Но пока, мы сосредоточимся только на основных запросах.

Использование запроса SELECT для выборки нужных данных Чтобы получить информацию, хранящуюся в базе данных, используется запрос SELECT. Базовое действие этого запроса ограничено одной таблицей, хотя существуют конструкции, обеспечивающие выборку с нескольких таблиц одновременно. Для того, чтобы получить все строки данных для специфических столбцов, используется запрос такого вида:

SELECT column1, column2 FROM table_name;

Также, можно получить все столбцы из таблицы, используя подстановочный знак «*»: SELECT * FROM table_name;

Это может быть полезно в том случае, когда вы собираетесь выбрать данные с определенным условием WHERE. Следующий запрос возвратит все столбцы со всех строк, где «column1»

содержит значение «3»: SELECT * FROM table_name WHERE column1=3;

Кроме «=» (равно), существуют следующие условные операторы:

Условные операторы = Равно Не равно Больше Меньше = Больше или равно = Меньше или равно Использование запроса INSERT для вставки новых данных Запрос INSERT используется для создания новой строки данных. Для обновления уже существующих данных или пустых полей строки нужно использовать запрос UPDATE.

Примерный синтаксис запроса INSERT:

INSERT INTO table_name (column1, column2, column3) VALUES (‘data1’, ‘data2’, ‘data3’);

Если вы собираетесь вставлять все значения в порядке, в котором находятся столбцы таблицы, то можно и не указывать имена столбцов, хотя для удобочитаемости это предпочтительнее.

Запрос UPDATE и условие WHERE. UPDATE используется для того, чтобы изменить существующие значения или освободить поле в строке, поэтому новые значения должны соответствовать существующему типу данных и обеспечивать приемлемые значения. Если вы не хотите изменить значения во всех строках, то нужно использовать условие WHERE.

UPDATE table_name SET column1 = ‘data1’, column2 = ‘data2’ WHERE column3 = ‘data3’;

Вы можете использовать WHERE для любого столбца, включая тот, который хотите изменить. Это используется когда необходимо заменить одно определенное значение на другое.

UPDATE table_name SET FirstName = ‘Василий’ WHERE FirstName = ‘Василий’ AND LastName = ‘Пупкин’;

Запрос DELETE полностью удаляет строку из базы данных. Если вы хотите удалить одно единственное поле, то нужно использовать запрос UPDATE и установить для этого поля значение, которое будет являться аналогом NULL в вашей программе. Будьте внимательны, и ограничивайте ваш запрос DELETE условием WHERE, иначе вы можете потерять все содержимое таблицы. DELETE FROM table_name WHERE column1 = ‘data1’;

Как только строка была удалена из вашей базы данных, она не подлежит восстановлению.

Выполнение работы Прежде чем приступить к написанию программы необходимо создать файл базы данных MS Access. Файл должен называться storehouse.mdb и размещаться в каталоге C:\Data\.

База данных должна содержать две таблицы, структура и название которых показаны ниже (рис.1,2):

Рис.1 – Структура БД Рис.2 – Структура БД Создайте новый проект Windows Forms Application. Технология создания проекта показана на рисунке 3. Надо выбрать тип проекта и задать его имя.

Рис.3– Начало работы с формой 2. Главную форму оформите следующим образом (рис.4):

Рис.4 – Макет формы приложения Для задания свойств элементов формы воспользуйтесь окном Properties (Свойства) (рис.5).

Рис.5. – Описание свойств формы 3. Создайте две дополнительных формы (Project/Add New Item…/Windows Form) для добавления поставщика и оформления поступления товаров (рис.6):

Рис.6 – Макет формы добавления поставщиков Задайте свойства формы:

1. AcceptButton – button 2. CancelButton – button 3. FormBorderStyle – FixedDialog 4. StartPosition – CenterScreen 5. TopMost – True 6. Text – Добавление поставщика Задайте свойства компонентов TextBox:

1. Modifiers – Public Дважды щелкните на кнопку «Сохранить», размещенную на форме, в режиме дизайна.

Среда VisualStudio создаст необходимую процедуру, которая будет исполняться при нажатии на кнопку. Созданная процедура должна выглядеть следующим образом:

private void button1_Click(object sender, EventArgs e) { DialogResult = DialogResult.OK;

} Аналогично проделайте с кнопкой «Отменить». Созданная процедура должна выглядеть следующим образом:

private void button2_Click(object sender, EventArgs e) { DialogResult = DialogResult.Cancel;

} Форма добавления товара должна выглядеть следующим образом (рис.7):

Рис.7 – Макет формы добавления товаров Установите аналогичные форме Добавления поставщика свойства формы. Создайте процедуры кнопок «Сохранить» и «Отменить» аналогично форме Добавления поставщика.

4. Перейдите на главную форму в режиме дизайна. Создайте процедуру кнопки «Добавить поставщика». Процедура должна выглядеть следующим образом:

private void button1_Click(object sender, EventArgs e) { AddSupplier addSupplier = new AddSupplier();

addSupplier.ShowDialog();

if ((addSupplier.DialogResult == DialogResult.OK) && (addSupplier.textBox1.Text.Length != 0)) { OleDbCommand comAddSupplier = new OleDbCommand(queryAddSupplier + "'" + addSupplier.textBox1.Text + "','" + addSupplier.textBox2.Text + "')", connection);

comAddSupplier.ExecuteNonQuery();

comAddSupplier.Dispose();

LoadDataSuplier();

} } Аналогично создайте процедуру кнопки «Оформить поступление товара». Процедура должна выглядеть следующим образом:

private void button2_Click(object sender, EventArgs e) { AddGoods addGoods = new AddGoods();

addGoods.ShowDialog();

if (addGoods.DialogResult == DialogResult.OK) { OleDbDataReader reader = comSupplier.ExecuteReader();

string codeSupplier = "";

while (reader.Read()) { if (reader["Наименование"].Equals(comboBox1.Items[comboBox1.SelectedIndex].ToString())) { codeSupplier = reader["КодПоставщика"].ToString();

} } reader.Close();

MessageBox.Show(codeSupplier);

if (codeSupplier == "") return;

OleDbCommand comAddGoods = new OleDbCommand(queryAddGoods + "'" + addGoods.textBox1.Text + "'," + addGoods.textBox2.Text + ","+codeSupplier+")", connection);

comAddGoods.ExecuteNonQuery();

comAddGoods.Dispose();

LoadDataGoods();

} } В режиме дизайна формы дважды щелкните по выпадающему списку. Созданная процедура должна выглядеть следующим образом:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { LoadDataGoods();

} Дважды щелкнув по главной форме (именно по форме или ее заголовку, а не по компоненту пользовательского интерфейса), создайте процедуру, которая будет выполняться при старте программы:

private void Form1_Load(object sender, EventArgs e) { //подключение к БД на основе строки подключения connection = new OleDbConnection(connectionString);

connection.Open();

//загрузка данных из таблицы Поставщики в выпадающий список LoadDataSuplier();

if (comboBox1.Items.Count != 0) comboBox1.SelectedIndex = 0;

} 5. В тексте программы главной формы необходимо вписать настройки подключения к базе данных и процедуры загрузки данных. В целом код программы главной формы должен выглядеть следующим образом:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

//для работы с БД необходимо подключить следующие модули:

using System.Data.OleDb;

namespace BD_MY { public partial class Form1 : Form { public Form1() { InitializeComponent();

} //строка подключения к БД string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;

Data Source=" + "c:\\Data\\storehouse.mdb;

User Id=admin;

Password=;

";

//строка запроса для выборки данных о поставщиках string querySupplier = "SELECT КодПоставщика, Наименование, Адрес from Поставщики ";

//строка запроса для добавления данных о поставщике string queryAddSupplier = "INSERT INTO Поставщики(Наименование,Адрес) VALUES (";

//строка запроса для выборки данных о товарах string queryGoods = "SELECT КодТовара, Наименование, Цена, КодПоставщика from Товары";

//строка запроса для добавления данных о поставщике string queryAddGoods = "INSERT INTO Товары(Наименование,Цена,КодПоставщика) VALUES (";

//экземпляр класса, содержащий произведенную выборку о Поставщиках OleDbCommand comSupplier = null;

//экземпляр класса, содержащий произведенную выборку о Товарах OleDbCommand comGoods = null;

//экземпляр класса подключения к БД OleDbConnection connection = null;

private void Form1_Load(object sender, EventArgs e) { //подключение к БД на основе строки подключения connection = new OleDbConnection(connectionString);

connection.Open();

//загрузка данных из таблицы Поставщики в выпадающий список LoadDataSuplier();

if (comboBox1.Items.Count != 0) comboBox1.SelectedIndex = 0;

} private void LoadDataSuplier() { comSupplier = new OleDbCommand(querySupplier, connection);

try { OleDbDataReader reader = comSupplier.ExecuteReader();

comboBox1.Items.Clear();

while (reader.Read()) { comboBox1.Items.Add(reader["Наименование"]);

} reader.Close();

} catch (Exception ex) { MessageBox.Show(ex.Message);

} } private void LoadDataGoods() { try { OleDbDataReader reader = comSupplier.ExecuteReader();

string codeSupplier = "";

while (reader.Read()) { if (reader["Наименование"].Equals(comboBox1.Items[comboBox1.SelectedIndex].ToString())) { codeSupplier = reader["КодПоставщика"].ToString();

} } reader.Close();

if (codeSupplier == "") return;

comGoods = new OleDbCommand(queryGoods + " WHERE КодПоставщика=" + codeSupplier, connection);

reader = comGoods.ExecuteReader();

listBox1.Items.Clear();

while (reader.Read()) { listBox1.Items.Add(reader["Наименование"]);

} reader.Close();

} catch (Exception ex) { MessageBox.Show(ex.Message);

} } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { LoadDataGoods();

} private void button1_Click(object sender, EventArgs e) { AddSupplier addSupplier = new AddSupplier();

addSupplier.ShowDialog();

if ((addSupplier.DialogResult == DialogResult.OK) && (addSupplier.textBox1.Text.Length != 0)) { OleDbCommand comAddSupplier = new OleDbCommand(queryAddSupplier + "'" + addSupplier.textBox1.Text + "','" + addSupplier.textBox2.Text + "')", connection);

comAddSupplier.ExecuteNonQuery();

comAddSupplier.Dispose();

LoadDataSuplier();

} } private void button2_Click(object sender, EventArgs e) { AddGoods addGoods = new AddGoods();

addGoods.ShowDialog();

if (addGoods.DialogResult == DialogResult.OK) { OleDbDataReader reader = comSupplier.ExecuteReader();

string codeSupplier = "";

while (reader.Read()) { if (reader["Наименование"].Equals(comboBox1.Items[comboBox1.SelectedIndex].ToString())) { codeSupplier = reader["КодПоставщика"].ToString();

} } reader.Close();

if (codeSupplier == "") return;

OleDbCommand comAddGoods = new OleDbCommand(queryAddGoods + "'" + addGoods.textBox1.Text + "'," + addGoods.textBox2.Text + ","+codeSupplier+")", connection);

comAddGoods.ExecuteNonQuery();

comAddGoods.Dispose();

LoadDataGoods();

} } } } 6. Запустите программу. Выполните отладку и тестирование. Исправьте ошибки, если такие имеются.

Задание для самостоятельной работы:

1. На главную форму добавьте кнопку «Удалить поставщика». Организуйте удаление записи о выбранном в выпадающем списке поставщике и всех товарах, которые он поставил.

2. Выполните подсчет общей суммы всех товаров, которые поставил выбранный поставщик, и выведите результат на экран с помощью компонента Label.

3. На главную форму добавьте кнопку «Редактировать поставщика». Организуйте правку записи о выбранном в выпадающем списке поставщике.

Для удаления поставщика:

private void button3_Click(object sender, EventArgs e) { OleDbDataReader reader = comSupplier.ExecuteReader();

string codeSupplier = "";

while (reader.Read()) { if (reader["Наименование"].Equals(comboBox1.Items[comboBox1.SelectedIndex].ToString())) { codeSupplier = reader["КодПоставщика"].ToString();

} } reader.Close();

if (codeSupplier == "") return;

OleDbCommand comDelete = new OleDbCommand("DELETE FROM Поставщики WHERE КодПоставщика="+codeSupplier, connection);

comDelete.ExecuteNonQuery();

comDelete.Dispose();

LoadDataSuplier();

} 1. Оценить сложность и качество прикладного алгоритма.

2. Оценить надежность, эффективность.

Результаты самостоятельной работы оформить в виде отчета.

Ответить на вопросы 1. Как работает механизм OleDb?

2. Опишите технологию работы с внешними источниками данных (БД).

3. Как задать свойства таблицы на главной форме?

4. Как вписать настройки подключения к базе данных и процедуры загрузки данных в главную форму прикладного алгоритма?

5. Как задать свойства компонентов?

Лабораторная работа №7. Современные технологии управления информационными потоками в экономических системах Цель: Закрепить навыки управления информационными потоками в экономических системах.

Разработать прототип интерфейса пользователя по управлению потоком информации.

Оценить соответствие программного продукта (приложение для пользователя) ТЗ и ТУ.

Задачи:

1. Изменить условие экономической задачи по результатам лабораторной работы 5,6.

2. В соответствии с требованиями ГОСТ 34.602-89 описать требования к модернизации Проекта.

Формируемые компетенции -навыки разработки приложений в соответствии со стандартами к надежности, защищенности и качеству ПП Задание:

1. Разработать контрольный список пользовательского интерфейса приложения (Лабораторная работа №5,6).

Модернизировать разработанное приложение в Лабораторной работе №6 следующим образом:

2. Добавить панели инструментов в приложение 3. Создать всплывающей подсказки для элементов управления 4. Создать контекстное меню и присоединить его к элементу управления 5. Добавить элементы управления во время выполнения программы Примеры выполнения по каждому требуемому пункту приведены ниже.

Теория Windows Forms представляет собой одну из двух технологий, используемую в Visual C# для создания интеллектуальных клиентских приложения на основе Windows, выполняемых в среде.NET Framework. Технология Windows Forms специально создана для быстрой разработки приложений, в которых обширный графический пользовательский интерфейс не является приоритетом. Для создания пользовательского интерфейса используется конструктор Windows Forms, и пользователь получает доступ к другим возможностям времени разработки и времени выполнения. Быстрота и удобство создания пользовательских интерфейсов в Visual C# обеспечивается благодаря Windows Form Designer или Windows Presentation Foundation (WPF) Designer. Создание пользовательских интерфейсов происходит в три основных этапа.

4. Добавление элементов управления на поверхность разработки.

5. Установка начальных свойств для элементов управления.

6. Написание обработчиков для заданных событий.

Хотя пользовательский интерфейс можно создать вручную, написав собственный код, с помощью конструкторов это можно сделать намного быстрее. Пользовательский интерфейс приложения можно настроить путем добавления стандартных панелей элементов и контекстных меню. Кроме того, к элементам управления можно добавить всплывающие подсказки, контекстное меню (меню, вызываемое при нажатии правой кнопки по элементу пользовательского интерфейса). Пример контрольного списка. Использование контрольных списков является эффективным и экономичным средством повышения уровня качества программных продуктов. Их использование, применительно к интерфейсу, не требует выполнения дорогостоящих процедур юзабилити-тестирования, достаточно большое количество контрольных списков по интерфейсу можно найти в интернете в свободном доступе. Естественно, что в каждом конкретном случае необходимо разрабатывать свой собственный контрольный список, поскольку он должен учитывать специфику разрабатываемого программного средства и возможности средств разработки. Поэтому настоящий контрольный список является скорее шаблоном, в котором представлены основные разделы. При разработке, тестировании и оценке качества пользовательского интерфейса необходимо применять соответствующие государственные и отраслевые стандарты. Однако это сразу порождает целый ряд вопросов, например: как стандарты соотносятся с различными аспектами пользовательского интерфейса? Что такое правильный интерфейс? Как применять эргономические стандарты при проектировании и тестировании интерфейса? Влияет ли стандартизация на качество разрабатываемых изделий?


Структура и классификация пользовательских интерфейсов В дизайне пользовательского интерфейса можно условно выделить декоративную и активную составляющие. К первой относятся элементы, отвечающие за эстетическую привлекательность программного изделия. Активные элементы подразделяются на операционные и информационные образы моделей вычислений и управляющие средства пользовательского интерфейса [2], посредством которых пользователь управляет программой. Управляющие средства различных классов программных изделий могут значительно различаться. Поэтому необходимо провести хотя бы предварительную классификацию интерфейсов и соответствующих им управляющих средств.

На первом уровне такой классификации полезно выделить классы интерфейсов, происхождение которых связано с используемыми базовыми техническими средствами человеко-машинного взаимодействия. Исторически, появление таких средств вызывает возникновение новых классов пользовательского интерфейса. Впрочем, с появлением новых средств использование интерфейсов старых классов не обязательно полностью прекращается. Классы интерфейса являются слишком широкими понятиями. Классы, задаваемые базовыми интерактивными средствами, целесообразно разбить на подклассы, например, в пределах графического класса различаются подклассы: двухмерные и трехмерные интерфейсы. По этой классификации широко распространенный интерфейс WIMP относится к первому из указанных подклассов. Сегодня развиваются такие новые классы интерфейсов, как SILK (речевой), биометрический (мимический) и семантический (общественный) [3]. В основе управляющих средств пользовательского интерфейса лежит тот или иной интерфейсный язык. При этом роль синтаксиса играют используемые графические образы и их динамические свойства. О типах управляющих средств пользовательского интерфейса мы будем говорить, имея в виду различные формы (элементы дизайна) типизированных управляющих элементов пользовательского интерфейса определенного подкласса. Дизайн конкретных реализаций интерфейса может включать композицию, вообще говоря, различных типов управляющих средств, информационные образы предметной области и декоративные элементы (в первую очередь метафоры интерфейса). Компоненты дизайна не произвольны, а образуют некоторое стилевое единство. Система управляющих средств пользовательского интерфейса конкретного подкласса является одновременно шаблоном возможного «текста» на некотором (неявном) языке пиктограмм управления и имитацией с помощью средств машинной графики управляющей панели инструмента обработки данных. В разных типах интерфейса удельная роль языковой и имитационной составляющей может быть различной. Показатель синтаксической правильности пользовательского интерфейса вводится в предположении существование некоторого эталона «правильного» интерфейса, в качестве которого естественно считать нормативные документы (стандарты), содержащие явное или неявное описание синтаксиса на уровне пиктограмм и способов манипуляции ими.

Знаковая система графического пользовательского интерфейса определяется конечным словарем графических управляющих элементов (ГУЭ). Каждый ГУЭ обладает стандартизированными свойствами описанного вида, составляющими его регламент.

Нарушение регламента ГУЭ следует рассматривать как ошибку проектирования пользовательского интерфейса. Правильность управляющих средств пользовательского интерфейса конкретного приложения — это соответствие управляющих средств синтаксису интерфейсов соответствующего типа.

Для экспертной оценки правильности управляющих средств пользовательского интерфейса на основе таких стандартов удается сформировать списки оценочных элементов (в терминах ГОСТ 28195-89 «Оценка качества программных продуктов. Общие положения»).

В англоязычной литературе говорят о контрольных списках (cheklists). Обратим внимание на отличие элементов контрольных списков от тестов (test cases), используемых при обычном тестировании. Обычные тесты являются конкретными частными значениями входных данных, в то время как элементы контрольных списков — это обобщенные правила оформления и функционирования управляющих средств пользовательского интерфейса.

Тестирование правильности пользовательского интерфейса возможно, если в формулировке требований к пользовательскому интерфейсу в техническом задании на программный продукт указывается тип (стиль) выбранного интерфейса, что, кстати, требует ГОСТ Р ИСО/МЭК 12119-2000 (п. 3.1.5).

Каждый элемент списка содержит на конце точку или начинается с прописной буквы по следующему правилу: «Текст всех элементов начинается со строчной буквы. Все элементы оканчиваются по последней букве слова без каких-либо знаков препинания, кроме последнего, который оканчивается точкой. Исключение: если хоть один элемент списка содержит более одного предложения, все элементы начинаются с заглавной буквы и заканчиваются точкой». Любому списку предшествует, по меньшей мере, один абзац текста.

В таблицах все столбцы с цифрами выравниваются по правому краю. Точка в конце фразы отсутствует в заголовке (если он отделен от текста), в конце подписи под рисунком и в таблице. Подписи к интерфейсным элементам начинаются с прописной буквы и заканчиваются двоеточием.

Выполнение работы Добавить панели инструментов в приложение В приложение можно без труда добавить панель инструментов, добавив элемент управления ToolStrip и затем добавив кнопки на панель инструментов. Можно добавлять отдельные элементы управления ToolStripButton или выбрать элемент из группы, например элемент управления ToolStripTextBox.

С помощью области задач ToolStrip можно легко добавить набор стандартных кнопок на панель инструментов. Эта область задач позволяет вставить семь стандартных кнопок на панель инструментов, как показано на следующем рисунке (рис.1).

Рис.1 – Вставка элементов Добавление набора стандартных кнопок панели инструментов 1. Перетащите элемент управления ToolStrip из панели элементов в форму.

В области компонентов появится элемент "ToolStrip1", а в верхнюю часть формы добавится панель инструментов.

2. Добавьте в форму элемент управления TextBox с именем по умолчанию "textBox1".

3. Щелкните элемент управления TextBox и измените следующие свойства в окне Свойства (рис.2).

Свойство Значение Размер 260, Текст Это простое тестирование Рис.2 – Изменение свойств 4. Выберите элемент управления ToolStrip, щелкните стрелку запуска задачи в правом верхнем углу элемента управления, затем выберите Вставить стандартные элементы.

В панели инструментов отобразятся семь стандартных кнопок (Создать, Открыть, Сохранить, Печать, Вырезать, Копировать, Вставить и Справка).

5. Дважды щелкните элемент управления CutToolStripButton, чтобы добавить обработчик событий по умолчанию Click, и добавьте следующий код. Этот код вырезает выделенный текст из TextBox1 и копирует его в буфер обмена.

this.textBox1.Cut();

  Протестируйте пример. Создайте панель инструментов с элементами, состав которых определяется по вашему усмотрению.

2. Создать всплывающей подсказки для элементов управления Для примера необходимы следующие компоненты:

Форма с именем Form1.

Элемент управления TextBox с именем textBox1.

Обработчик событий load для Form1 со значением Form1_Load.

В этом примере программно создается объект ToolTip для элемента управления Windows Forms.

private void Form1_Load(object sender, System.EventArgs e) { System.Windows.Forms.ToolTip ToolTip1 = new System.Windows.Forms.ToolTip();

ToolTip1.SetToolTip(this.textBox1, "Hello");

} Протестируйте пример. Создайте всплывающие подсказки ко всем элементам пользовательского интерфейса в приложении (Лабораторная работа №5).

3. Создать контекстное меню и присоединить его к элементу управления Для этого примера необходимы следующие компоненты.

Форма Windows Form с именем Form элемент управления TextBox с именем textBox Щелкните форму и вставьте код в обработчик событий Load. При выполнении приложения и щелчке правой клавишей мыши textBox1 в контекстном меню будут отображены три команды.

В этом примере программно создается ContextMenu Windows Forms и связывается с элементом управления.

private void Form1_Load(object sender, System.EventArgs e) { System.Windows.Forms.ContextMenu contextMenu1;

contextMenu1 = new System.Windows.Forms.ContextMenu();

System.Windows.Forms.MenuItem menuItem1;

menuItem1 = new System.Windows.Forms.MenuItem();

System.Windows.Forms.MenuItem menuItem2;

menuItem2 = new System.Windows.Forms.MenuItem();

System.Windows.Forms.MenuItem menuItem3;

menuItem3 = new System.Windows.Forms.MenuItem();

contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {menuItem1, menuItem2, menuItem3});

menuItem1.Index = 0;

menuItem1.Text = "MenuItem1";

menuItem2.Index = 1;

menuItem2.Text = "MenuItem2";

menuItem3.Index = 2;

menuItem3.Text = "MenuItem3";

textBox1.ContextMenu = contextMenu1;

} Протестируйте пример. Создайте контекстное меню (состав меню – по вашему усмотрению) ко всем элементам пользовательского интерфейса в приложении (Лабораторная работа №5).

4. Добавить элементы управления во время выполнения программы В этом примере новый экземпляр элемента управления TextBox Windows Forms создается во время выполнения. В этом примере требуется ссылка на пространство имен System.Windows.Forms.

private void Form1_Load(object sender, System.EventArgs e) { TextBox MyTextBox = new System.Windows.Forms.TextBox();

MyTextBox.Location = new System.Drawing.Point(64, 40);

MyTextBox.Name = "MyTextBox";

MyTextBox.Size = new System.Drawing.Size(88, 21);

MyTextBox.TabIndex = 0;

MyTextBox.Text = "MyTextBox";

Controls.Add(MyTextBox);

// Adding the DoubleClick event.

MyTextBox.DoubleClick += new EventHandler(MyTextBox_DoubleClick);

} private void MyTextBox_DoubleClick(object sender, System.EventArgs e) { MessageBox.Show("MyTextBox doubleClick event.");


} Протестируйте пример. Определите, какие элементы пользовательского интерфейса в разработанном приложении Лабораторной работы №5 целесообразно создавать динамически (во время выполнения программы) и разработайте соответствующие процедуры/функции.

Контрольные вопросы 1. Какие требования предъявляют стандарты в пользовательскому интерфейсу?

2. Как можно оценить пользовательский интерфейс на соответствие требованиям стандартов?

3. Какие управляющие элементы являются обязательными при проектировании пользовательского интерфейса?

Лабораторная работа №8. Стандартизация требований к современным интерфейсам пользователей Цель: Изучить требования стандартов к разработке надежного и качественного программного обеспечения. Оценка качества программного обеспечения и сложности алгоритмов на основе ТУ Оценить соответствие программного продукта (приложение для пользователя) ТЗ и ТУ.

Задачи:

1. Ознакомиться с теорией создания контрольных списков пользовательского интерфейса.

2. Акцентировать внимание на требованиях стандартов к качеству разработки интерфейса пользователя.

3. Проанализировать имеющийся интерфейс пользователя на соответствие стандартов.

4. Разработать приложение пользователя в соответствии с требованиями стандартов.

5. Оценить качество и надежность собственного ПО.

6. Оценить его требованиям ТЗ, и сравнить с требованиями ТУ.

Формируемые компетенции -навыки разработки приложений в соответствии со стандартами к надежности, защищенности и качеству ПП Задание:

1. Разработать контрольный список пользовательского интерфейса приложения (Лабораторная работа №5,6).

Модернизировать разработанное приложение в Лабораторной работе №6 следующим образом:

2. Добавить панели инструментов в приложение 3. Создать всплывающей подсказки для элементов управления 4. Создать контекстное меню и присоединить его к элементу управления 5. Добавить элементы управления во время выполнения программы Примеры выполнения по каждому требуемому пункту приведены ниже.

Теория Windows Forms представляет собой одну из двух технологий, используемую в Visual C# для создания интеллектуальных клиентских приложения на основе Windows, выполняемых в среде.NET Framework. Технология Windows Forms специально создана для быстрой разработки приложений, в которых обширный графический пользовательский интерфейс не является приоритетом. Для создания пользовательского интерфейса используется конструктор Windows Forms, и пользователь получает доступ к другим возможностям времени разработки и времени выполнения. Быстрота и удобство создания пользовательских интерфейсов в Visual C# обеспечивается благодаря Windows Form Designer или Windows Presentation Foundation (WPF) Designer. Создание пользовательских интерфейсов происходит в три основных этапа.

7. Добавление элементов управления на поверхность разработки.

8. Установка начальных свойств для элементов управления.

9. Написание обработчиков для заданных событий.

Хотя пользовательский интерфейс можно создать вручную, написав собственный код, с помощью конструкторов это можно сделать намного быстрее. Пользовательский интерфейс приложения можно настроить путем добавления стандартных панелей элементов и контекстных меню. Кроме того, к элементам управления можно добавить всплывающие подсказки, контекстное меню (меню, вызываемое при нажатии правой кнопки по элементу пользовательского интерфейса). Пример контрольного списка. Использование контрольных списков является эффективным и экономичным средством повышения уровня качества программных продуктов. Их использование, применительно к интерфейсу, не требует выполнения дорогостоящих процедур юзабилити-тестирования, достаточно большое количество контрольных списков по интерфейсу можно найти в интернете в свободном доступе. Естественно, что в каждом конкретном случае необходимо разрабатывать свой собственный контрольный список, поскольку он должен учитывать специфику разрабатываемого программного средства и возможности средств разработки. Поэтому настоящий контрольный список является скорее шаблоном, в котором представлены основные разделы. При разработке, тестировании и оценке качества пользовательского интерфейса необходимо применять соответствующие государственные и отраслевые стандарты. Однако это сразу порождает целый ряд вопросов, например: как стандарты соотносятся с различными аспектами пользовательского интерфейса? Что такое правильный интерфейс? Как применять эргономические стандарты при проектировании и тестировании интерфейса? Влияет ли стандартизация на качество разрабатываемых изделий?

В дизайне пользовательского интерфейса можно условно выделить декоративную и активную составляющие. К первой относятся элементы, отвечающие за эстетическую привлекательность программного изделия. Активные элементы подразделяются на операционные и информационные образы моделей вычислений и управляющие средства пользовательского интерфейса [2], посредством которых пользователь управляет программой. Управляющие средства различных классов программных изделий могут значительно различаться. Поэтому необходимо провести хотя бы предварительную классификацию интерфейсов и соответствующих им управляющих средств.

На первом уровне такой классификации полезно выделить классы интерфейсов, происхождение которых связано с используемыми базовыми техническими средствами человеко-машинного взаимодействия. Исторически, появление таких средств вызывает возникновение новых классов пользовательского интерфейса. Впрочем, с появлением новых средств использование интерфейсов старых классов не обязательно полностью прекращается. Классы интерфейса являются слишком широкими понятиями. Классы, задаваемые базовыми интерактивными средствами, целесообразно разбить на подклассы, например, в пределах графического класса различаются подклассы: двухмерные и трехмерные интерфейсы. По этой классификации широко распространенный интерфейс WIMP относится к первому из указанных подклассов. Сегодня развиваются такие новые классы интерфейсов, как SILK (речевой), биометрический (мимический) и семантический (общественный) [3]. В основе управляющих средств пользовательского интерфейса лежит тот или иной интерфейсный язык. При этом роль синтаксиса играют используемые графические образы и их динамические свойства. О типах управляющих средств пользовательского интерфейса мы будем говорить, имея в виду различные формы (элементы дизайна) типизированных управляющих элементов пользовательского интерфейса определенного подкласса. Дизайн конкретных реализаций интерфейса может включать композицию, вообще говоря, различных типов управляющих средств, информационные образы предметной области и декоративные элементы (в первую очередь метафоры интерфейса). Компоненты дизайна не произвольны, а образуют некоторое стилевое единство. Система управляющих средств пользовательского интерфейса конкретного подкласса является одновременно шаблоном возможного «текста» на некотором (неявном) языке пиктограмм управления и имитацией с помощью средств машинной графики управляющей панели инструмента обработки данных. В разных типах интерфейса удельная роль языковой и имитационной составляющей может быть различной. Показатель синтаксической правильности пользовательского интерфейса вводится в предположении существование некоторого эталона «правильного» интерфейса, в качестве которого естественно считать нормативные документы (стандарты), содержащие явное или неявное описание синтаксиса на уровне пиктограмм и способов манипуляции ими.

Знаковая система графического пользовательского интерфейса определяется конечным словарем графических управляющих элементов (ГУЭ). Каждый ГУЭ обладает стандартизированными свойствами описанного вида, составляющими его регламент.

Нарушение регламента ГУЭ следует рассматривать как ошибку проектирования пользовательского интерфейса. Правильность управляющих средств пользовательского интерфейса конкретного приложения — это соответствие управляющих средств синтаксису интерфейсов соответствующего типа. Для экспертной оценки правильности управляющих средств пользовательского интерфейса на основе таких стандартов удается сформировать списки оценочных элементов (в терминах ГОСТ 28195-89 «Оценка качества программных продуктов. Общие положения»). В англоязычной литературе говорят о контрольных списках (cheklists). Обратим внимание на отличие элементов контрольных списков от тестов (test cases), используемых при обычном тестировании. Обычные тесты являются конкретными частными значениями входных данных, в то время как элементы контрольных списков — это обобщенные правила оформления и функционирования управляющих средств пользовательского интерфейса. Тестирование правильности пользовательского интерфейса возможно, если в формулировке требований к пользовательскому интерфейсу в техническом задании на программный продукт указывается тип (стиль) выбранного интерфейса, что, кстати, требует ГОСТ Р ИСО/МЭК 12119-2000 (п. 3.1.5).

Качество интерфейса — эргономический аспект. Качество определяется в ГОСТ Р ИСО/МЭК 9126-93 как «объем признаков и характеристик продукции или услуги, который относится к их способности удовлетворять установленным или предполагаемым потребностям». При комплексной оценке показателей качества программного продукта качество пользовательского интерфейса вносит определяющий вклад в такую субхарактеристику качества, как практичность (usability) (ГОСТ Р ИСО/МЭК 9126-93. С семиотической точки зрения качество соотносится со стандартизированностью как семантика и прагматика с синтактикой. Другими словами, качество характеризует содержание (смысл) и полезность текста, в то время как стандартизированность — грамотность (корректность). В качестве пользовательского интерфейса можно выделить два аспекта интерфейса — функциональный и эргономический. О качестве функциональности интерфейса трудно говорить безотносительно предметной области, например, сформулировать «руководящие принципы функциональности» пользовательского интерфейса. Формально его можно связать со степенью «соответствия задаче» (ISO 9241-10 1996, p.10).

Нормативные требования по эргономике пользовательского интерфейса отличаются по своей природе от синтаксических и манипуляционных правил — они относятся к психофизиологическим свойствам конкретной реализации уже выбранного типа (стиля) пользовательского интерфейса (и соответствующего стандарта) в конкретном приложении. В этих условиях эргономические стандарты могут лишь требовать достижения некоторых общих руководящих эргономических принципов [9], которым должно удовлетворять реализация в приложении выбранного тип (стиля). При этом предполагается, что приложение должно оптимально инкорпорировано в техническую среду. При разработке, тестировании и оценке качества пользовательского интерфейса необходимо применять соответствующие государственные и отраслевые стандарты.

В первом подходе оценку производит конечный пользователь (или тестер), суммируя результаты работы с программой в рамках следующих показателей ISO 9241-10- Ergonomic requirements for office work with visual display terminals (VDTs). P. 11. Guidance on usability specification and measures:

• эффективности (effectiveness) - влияния интерфейса на полноту и точность достижения пользователем целевых результатов;

• продуктивности (efficiency) или влияния интерфейса на производительность пользователя;

• степени (субъективной) удовлетворенности (satisfaction) конечного пользователя этим интерфейсом.

Эффективность является критерием функциональности интерфейса, а степень удовлетворенности и, косвенно, продуктивность — критерием эргономичности. Вводимые здесь меры соответствуют общей прагматической концепции оценки качества по соотношению «цели/затраты».

Во втором подходе пытаются установить, каким (руководящим эргономическим) принципам должен удовлетворять пользовательский интерфейс с точки зрения оптимальности человеко-машинного взаимодействия. Развитие этого аналитического подхода было вызвано потребностями проектирования и разработки ПО, поскольку позволяет сформулировать руководящие указания по организации и характеристикам оптимального пользовательского интерфейса. Этот подход может быть использован и при оценке качества разработанного пользовательского интерфейса. В этом случае показатель качества оценивается экспертом по степени реализации руководящих принципов или вытекающих из них более конкретных графических и операционных особенностей оптимального «человеко-ориентированного» пользовательского интерфейса.

Стандарты и качество. Формально стандартизированность пользовательского интерфейса уместно связать с другими инфраструктурными субхарактеристиками качества программного продукта, такими, как соответствие (conformance) (в том числе и соответствие стандартам) и взаимозаменяемость (replaceability) (ГОСТ Р ИСО МЭК 9126-93). Выбор конкретного средства проектирования (языки быстрой разработки приложений, CASE средства, конструкторы графических интерфейсов) может привести разработчика к необходимости придерживаться стандарта интерфейса, положенного в его основу.С другой стороны, выбор разработчиком стандарта типа (стиля) пользовательского интерфейса, адекватного предметной области и используемой ОС, потенциально должен обеспечить, хотя бы отчасти, выполнение таких принципов качества пользовательского интерфейса, как естественность и согласованность в пределах рабочей среды [13].

Все кнопки, запускающие действия, имеют текст в инфинитивной форме глагола (пример: искать), а не другую часть речи либо форму глагола (пример: готово). Давать кнопке текст «ОК» можно, только если какой-либо глагол не вмещается. Кликабельный размер кнопок совпадает с их видимым или логическим размером. Между кнопками, стоящими рядом, должно быть пустое пространство, щелчок по которому не отрабатывается.

Нет разных состояний кнопок, которые выглядят одинаково. Недоступные команды не исчезают с экрана, а становятся заблокированными. Частотные кнопки снабжены не только текстом, но и пиктограммами;

редко используемые кнопки - только текстовыми подписями.

В модальных диалоговых окнах нет кнопок «Применить».

Поля ввода. В полях ввода уже стоят наиболее вероятные значения. Если в поле вводится численное значение, границы диапазона выводятся во всплывающей подсказке.

Если в поле вводится численное значение из ограниченного диапазона, поле снабжено крутилкой (Spinner). Длина полей не меньше, и, по возможности, не больше, длины вводимых в них данных. Если поле предназначено для ввода заметного количества текста, оно многострочное. Многострочные поля имеют максимально возможную высоту;

нет резервов для их увеличения.

Списки. В списках уже стоят наиболее вероятные значения. Если список содержит более 50 элементов, используется фильтр или режим поиска. Нет часто используемых коротких списков (менее пяти элементов);

такие списки представлены как группы радиокнопок или чекбоксов. Ширина списков не меньше ширины входящих в них элементов.

Элементы списка отсортированы;

либо структурно, т.е. по общим признакам, либо по алфавиту, либо по частотности (только списки меньше 7 элементов). Если в списке более отсортированных по алфавиту элементов, первыми тремя элементами являются наиболее частотные элементы. Они также повторяются на своих алфавитных местах. Многострочные списки множественного выбора снабжены чекбоксами возле каждого элемента (списки старого стиля отсутствуют). Многострочные списки имеют высоту не менее 4 строк. Если есть свободное место, используются расширенные комбобоксы, а не однострочные.

Чекбоксы и радиокнопки. Если чекбоксов в группе больше 10, вводится дополнительный, выставляющий/снимающий все чекбоксы. Внутри группы радиокнопок одна обязательно установлена по умолчанию. Чекбоксы и радиокнопки внутри своих групп расставлены по вертикали. Если в окне, помимо терминационных кнопок, есть только набор радиокнопок, двойной щелчок по радиокнопке устанавливает ее и закрывает окно.

Взаимодействие. Система, завершив длительную операцию (больше минуты работы), пищит через встроенный динамик компьютера. Если в интерфейсе не используется непосредственного манипулирования, система не имеет своих курсоров. Если непосредственное манипулирование применяется, свои курсоры применяются, только если аналогов из ОС не существует.

Системные сообщения и отработка ошибок. В формах ввода проверка корректности вводимых значений выполняется прямо во время ввода;

если вводятся некорректные данные, система сразу сообщает об этом пользователю, не дожидаясь момента, когда пользователь завершит ввод данных во всей форме. Сообщения о некорректности введенных данных показываются рядом с элементом управления, данные в котором некорректны. Текст сообщений о некорректности введенных данных не говорит, что, дескать, совершена ошибка, напротив, он только информирует пользователя, данные какого типа и формата приемлемы.

Если окно с текстом о некорректности введенных данных всплывающее — оно не должно заслонять собой поле ввода, где содержится текст с ошибкой. Текст сообщений о проблемах состоит из трех частей: в первой кратко описывается проблема, во второй части - как ее решить, в третьей - описывается, как не допускать возникновения этой проблемы в дальнейшем. Статусные сообщения («Синхронизация успешно завершена») выводятся только в строке статуса.

Клавиатура. В формах ввода нажатие табуляции ведет к правильной последовательности перемещения по форме. Обработка формы запускается не только по нажатию на терминационую кнопку, но и по нажатию клавиши Enter на последнем поле этой формы. Для наиболее частотных элементов управления (включая меню) установлены клавиши быстрого вызова. Каждому пункту меню назначены ALT-комбинации (выделены подчеркиванием). ALT-комбинации и горячие клавиши стандартные. Если горячих клавиш больше 40, в интерфейсе есть способ их изменить. По нажатию клавиши Tab переход от элемента к элементу внутри формы осуществляется сверху вниз слева направо.

Индикация. Индикация цветом не является единственной;

если она используется, система снабжена и другой индикацией.

Пиктограммы. В группах пиктограмм нет пиктограмм, по цвету и форме сходных между собой. Нет пиктограмм со стандартными значениями, но нестандартными сюжетами.

В пиктограммах нет текста. В наборах пиктограмм пиктограммы одного значения, но разных размеров используют одни и те же особенности и/или сюжет.

Окна. На растягивающихся окнах есть индикатор растягиваемости. Заголовки окон соответствуют названиям элементов, при помощи которых окна были вызваны. Если окно вызывается элементом, не имеющим явного названия, в заголовке окна отражается название экранной формы. Тип окна (модальное, немодальное, возможность минимизации/максимизации) был выбран осознанно, в соответствии с задачами пользователей. В диалоговых окнах отсутствуют меню или инструментальные панели.

Кнопки Применить используются только в окнах-палитрах (вместо кнопок ОК).

Строка статуса. В строке статуса выводится только информация о текущем состоянии системы и кнопки (не выглядящие кнопками) для функций, предназначенных только опытным пользователям. Индикаторы выполнения выводятся в строке статуса.

Исключение: окна-маcтера, в них индикаторы выполнения можно выводить внутри самих окон.

Меню. Первая буква в названии пунктов меню - заглавная. Все пункты меню первого уровня активизируют раскрывающиеся меню. Используются не более двух подуровней меню. Если в меню есть пиктограммы, ими снабжены только самые частотные элементы.

Элементы, открывающие вложенные меню, выглядят иначе, чем терминальные элементы.



Pages:     | 1 |   ...   | 2 | 3 || 5 |
 





 
© 2013 www.libed.ru - «Бесплатная библиотека научно-практических конференций»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.