- •Организация c#-системы ввода-вывода: байтовые и символьные потоки. Встроенные потоки.
- •Классы потоков. Класс Stream. Классы байтовых потоков. Классы символьных потоков. Классы двоичных потоков.
- •1.5. Классы символьных потоков:
- •1.6. Классы двоичных потоков:
- •Класс FileStream и файловый ввод-вывод на побайтовой основе. Открытие и закрытие файла. Запись данных в файл. Считывание байтов из объекта класса FileStream.
- •Файловый ввод-вывод с ориентацией на символы. Использование класса StreamWriter. Использование класса StreamReader.
- •Считывание и запись двоичных данных. Класс BinaryWriter. Класс BinaryReader.
- •Наиболее важные методы выходного потока BinaryWriter:
- •Навигация по файловой системе: классы для работы с файловой системой.
- •Получение сведений о файле; копирование файлов; перечисление файлов в папке; изменение расширения файлов.
- •5.3. Изменение расширения файлов
- •Основы организации потоков. Потоки и многозадачность.
- •Пространство имен System.Threading. Класс Thread. Создание потока.
- •Создание потока. Чтобы создать поток, необходимо создать объект типа Thread. В классе Thread определен следующий конструктор: public Thread(ThreadStart entryPoint),
- •Приоритет потоков. Класс Thead поддерживает установку и получение приоритета потока. Для этого используется перечисление ThreadPriority. Его значения:
- •Использование нескольких потоков. Планирование потоков, приоритеты потоков. Можно создавать в программе несколько дочерних потоков.
- •Создать статический метод SimpleWork() в классе MultiThread (перед методом Main), который выводит на экран Id-номер каждого потока:
- •Проблемы одновременности и синхронизации потоков. Общий доступ к данным из разных потоков, предотвращение коллизий.
- •Синхронизация доступа к общим данным с помощью блокировок.
- •2) Выполнить блокировку операторов в ранее используемых методах SimpleWork и run:
- •Управление временем существования потоков.
- •Краткий обзор ado.Net. Три стороны технологии ado.Net. Пространство имен System.Data.
- •2.2 Три стороны технологии ado.Net
- •15.Поставщики данных ado.Net. Поведение объектов подключения.
- •Объектная модель ado.Net.
- •Создание соединения с источником данных. Члены типа dbConnection. Обработка исключений при работе с ms sql
- •Конструкторы
- •Свойства
- •События
- •Конструкторы
- •Свойства
- •Выборка, добавление, удаление и обновление данных с помощью sql-запросов на подсоединенном уровне.
- •Вывод информации с использованием объекта чтения данных: создание SqlDataReader; чтение данных из DataReader; чтение полей из текущей записи; закрытие DataReader.
- •Сравнение DataReader и DataSet:
- •Чтение данных из DataReader:
- •Организация хранения данных. Объект DataSet.
- •Строки: объект DataRow.
- •Конструкторы:
- •Свойства
- •Передача данных между источником данных и объектом DataSet. Обновление базы данных с помощью адаптера данных.
Создание потока. Чтобы создать поток, необходимо создать объект типа Thread. В классе Thread определен следующий конструктор: public Thread(ThreadStart entryPoint),
тип ThreadStart — это делегат, определенный в среде .NET Framework: public delegate void ThreadStart().
Итак, начальный метод должен иметь тип возвращаемого значения void и не принимать никаких аргументов. Выполнение созданного потока не начнется до тех пор, пока не будет вызван метод Start(), который определяется в классе Thread. Его определение выглядит так: public void Start().
Начавшись, выполнение потока будет продолжаться до тех пор, пока не завершится метод, заданный параметром entryPoint. Поэтому после выхода из entryPoint-метода выполнение потока автоматически завершается. Если попытаться вызвать метод Start() для потока, запущенного на выполнение, будет сгенерировано исключение типа ThreadStateException. После создания потока заданный метод начинает в нем свою работу, а первичный поток продолжает выполняться.
Приоритет потоков. Класс Thead поддерживает установку и получение приоритета потока. Для этого используется перечисление ThreadPriority. Его значения:
Highest Наивысший приоритет
Above Normal Приоритет выше обычного (Normal)
Normal Приоритет по умолчанию
Below Normal Приоритет ниже обычного
Lowest Самый низкий приоритет
В большинстве случаев следует использовать приоритет по умолчанию (Normal). Повышение или понижение приоритета может привести к тому, что операционной системе придется выделить некоторым потокам гораздо больше (или меньше) ресурсов, чем ожидалось. А если назначить некоторому потоку наивысший приоритет, остальные операции в системе могут просто остановиться. Порой повышать и понижать приоритет приходится, но делайте это с осторожностью. Надолго повысив приоритет одного потока, вы вряд ли сможете повысить производительность системы в целом, так как при этом возникнет нехватка ресурсов у других потоков, что может привести к непредсказуемым результатам.
Часто в многопоточной программе нужно позаботиться о том, чтобы основной поток завершался последним. Формально программа продолжает выполняться до тех пор, пока не завершатся все высокоприоритетные потоки. Таким образом, совсем необязательно завершение основного потока последним. Однако добиваться этого — считается одним из признаков хорошего стиля программирования, поскольку в этом случае ясно определяется конечная точка программы.
Использование нескольких потоков. Планирование потоков, приоритеты потоков. Можно создавать в программе несколько дочерних потоков.
Задание: Выполнить одну операцию в нескольких потоках.
Создать статический метод SimpleWork() в классе MultiThread (перед методом Main), который выводит на экран Id-номер каждого потока:
class MultiThread
{
static void SimpleWork()
{
Console.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId);
}
static void Main(string[] args)
{
ThreadStart operation = new ThreadStart(SimpleWork);
for (int x = 1; x <= 5; ++x)
{
// Создаем новый поток, но не запускаем его
Thread theThread = new Thread(operation);
// Запускаем задачу в новом потоке
theThread.Start();
}
Здесь заданная операция выполняется в пяти отдельных потоках. Синхронность работы этих потоков зависит от возможностей компьютера. После внесения этих изменений мы получим пять потоков, каждый из которых выводит в окне консоли собственный идентификатор:
Thread: 3 Thread: 4 Thread: 5 Thread: 6 Thread: 7
Номера потоков выводятся последовательно, так как выполняемая методом SimpleWork операция завершается очень быстро. Попробуем запрограммировать более сложную операцию, чтобы изучить синхронную работу потоков:
Задание: Замедлить работу потока, позволяя другим потокам продолжить выполнение.
static void SimpleWork()
{
for (int x = 1; x <= 10; ++x)
{
Console.WriteLine("Thread: " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Номер итерации " + x);
Thread.Sleep(50);
}
}
// В Main():
for (int x = 1; x <= 3; ++x)
{
Thread theThread = new Thread(operation);
theThread.Start();
}
В методе SimpleWork мы выводим на экран идентификатор потока (их три) 10 раз. Кроме того, мы используем Thread.Sleep, чтобы замедлить работу кода. Метод Thread.Sleep позволяет приостановить выполнение потока на заданное время (в миллисекундах), тогда как остальные потоки будут продолжать работу. Работа каждого потока останавливается на 50 миллисекунд, и другие потоки в это время выводят свои данные на консоль. Чтобы посмотреть, как это работает, мы изменили метод SimpleWork так, чтобы он показывал номер текущей итерации:
Thread:3 Thread:4 Thread:5 Thread:6 Thread:7 Thread:3 Thread: 4Thread:5 Thread:6 Thread:7
Это позволило достичь максимально параллельного выполнения операций, возможного для компьютера с данной конфигурацией.
