- •Графический интерфейс пользователей
- •Объектная модель программы
- •Основной элемент графического интерфейса – окна (windows)
- •Отношения между окнами
- •Типы окон
- •Программирование графического интерфейса (gui)
- •Содержание окна
- •Контекстное меню (ContextMenuStrip)
- •Библиотека api функций для рисования gdi32.Dll
- •Основной класс рисования Graphics
- •Основные методы класса Graphics
- •Получение объекта Graphics
- •Событие Paint
- •Выполнение рисования
- •Система координат. Система координат и единиц измерения
- •Классы для описания геометрических объектов
- •Операции с изображениями
- •Курсор мыши
- •Основные события устройства «мышь»
- •Размер окна
- •Свойство Anchor
- •Компоненты
- •Элементы управления для работы с принтером – Printing
- •Автоматизация создания программы
- •Окно списков ListBox
- •Коллекция элементов ListBox
- •Комбинированные окна ComboBox
- •Элемент CheckedListBox
- •Класс PictureBox
- •Элемент управления WebBrowser
- •Элемент управления ProgressBar
- •Элемент NumericUpDown
- •Подсказки – ToolTip
- •Процессы и потоки
- •Виды многопоточности:
- •Преимущества многопоточности
- •Случаи использования многопоточности:
- •Потоки в с#
- •Основные статические свойства:
- •Недостатки многопоточности
- •Методы управления потоками
- •Свойства потока.
- •Приоритеты потоков
- •Передача данных в ThreadStart
- •Управление потоками
- •Ресурсы, требующие синхронизации:
- •Простейшие методы блокировки.
- •Оператор lock
- •Класс Interlocked
- •Класс Monitor
- •Классы ManualResetEvent и AutoResetEvent
- •Атрибут [Synchronization]
- •Константы:
- •Минимально необходимые действия для использования BackgroundWorker:
- •Чтобы добавить отображение выполнения операции:
- •Чтобы иметь возможность отмены операции:
- •Задачи (класс Task)
- •Статусы задачи
- •Применение идентификатора задачи
- •Методы ожидания завершения задачи
- •Класс TaskFactory
- •Работа с данными в задаче
- •Вложенные задачи.
- •Механизм отмены задач.
- •Создание продолжения задачи
- •Шаблоны параллелизма Parallel
- •Метод For()
- •Досрочный выход из цикла
Передача данных в ThreadStart
Тип делегата ParametrizedThreadStart позволяет передать единственный параметр типа System.Object.
Т.к System.Object представляется все, что угодно, можно передать любое количество параметров через специальный класс или структуру.
Основные и фоновые потоки
По умолчанию потоки создаются как основные, что означает, что приложение не будет завершено, пока один из таких потоков будет исполняться. C# также поддерживает фоновые потоки, они не продлевают жизнь приложению, а завершаются сразу же, как только все основные потоки будут завершены.
Статус потока переключается с основного на фоновый при помощи свойства IsBackground.
Основные или потоки переднего плана (foreground threads) обеспечивают предохранение текущего приложения от завершения. Среда CLR не остановит приложение (что означает выгрузку текущего домена приложения) до тех пор, пока не будут завершены все эти потоки.
Фоновые потоки (background threads), иногда называемые потоками-демонами, воспринимаются средой CLR как расширяемые пути выполнения, которые в любой момент времени могут игнорироваться (даже если они в текущее время заняты выполнением некоторой части работы). Если все потоки переднего плана прекращаются, то все фоновые потоки автоматически уничтожаются при выгрузке домена приложения.
По умолчанию каждый поток, создаваемый через метод Thread.Start(), автоматически становится потоком переднего плана. Это означает, что домен приложения не выгрузится до тех пор, пока все потоки выполнения не завершат свою часть работы. В большинстве случаев именно такое поведение и нужно.
Чтобы создать фоновый поток необходимо установить свойство IsBackground в true.
Управление потоками
Поток создается за счет вызова метода Start() объекта Thread. Однако после вызова метода Start() новый поток все еще пребывает не в состоянии Running, а в состоянии Unstarted. В состояние Running поток переходит сразу после того, как планировщик потоков операционной системы выберет его для выполнения. Информация о текущем состоянии потока доступна через свойство Thread.ThreadState.
Вызов Thread.Sleep блокирует текущий поток на указанное время
Когда поток остановлен в результате этих конструкций, говорят, что он блокирован. Будучи блокированным, поток немедленно перестает получать время CPU, устанавливает свойство ThreadState в WaitSleepJoin и остается в таком состоянии, пока не разблокируется. Разблокировка может произойти в следующих четырех случаях:
выполнится условие разблокировки;
истечет таймаут операции (если он был задан);
по прерыванию через Thread.Interrupt;
по аварийному завершению через Thread.Abort.
Поток не считается блокированным, если его выполнение приостановлено нерекомендуемым методом Suspend
Отстранение потока от выполнения
Обеспечивается нестатическим методом Suspend(). Поток входит в "кому", из которой его можно вывести, вызвав метод Resume(). Этот вызов, должен исходить из другого потока. Если все не отстраненные от выполнения потоки оказались завершены и некому запустить отстраненный поток – приложение в буквальном смысле "зависает".
Завершение потоков
Поток завершается после выполнения ПОСЛЕДНЕГО оператора выполняемой цепочки операторов.
Поток может быть остановлен в результате выполнения метода Abort(). При выполнении этого метода происходит активация исключения ThreadAbortException. В том числе возможна и реанимация остановленного потока путем вызова метода ResetAbort().
Синхронизация потоков
Безопасность данных и критические секции кода
Некоторое значение, связанное с конкретным объектом, подвергается воздействию (изменению, преобразованию) со стороны потока. Это означает, что по отношению к объекту (значению объекта) применяется фиксированная последовательность операторов, в результате которой происходит КОРРЕКТНОЕ изменение состояния объекта или его значения.
В многопоточном приложении один и тот же объект может быть подвергнут одновременному "параллельному" воздействию со стороны нескольких потоков. Подобное воздействие представляет опасность для объекта и его значения, поскольку в этом случае порядок применения операторов из нескольких потоков (пусть даже и содержащих одни и те же операторы) неизбежно будет изменен.
В многопоточном программировании последовательности операторов, составляющих поток и при неконтролируемом доступе к объекту, возможно, приводящих к некорректному изменению состояния объекта, называются критическими секциями кода.
