- •Организация 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. Обновление базы данных с помощью адаптера данных.
Проблемы одновременности и синхронизации потоков. Общий доступ к данным из разных потоков, предотвращение коллизий.
При программировании для однопоточного окружения методы зачастую пишутся так, что на некоторых этапах исполнения кода объекты временно находятся в недействительном состоянии. Очевидно, что если в любой момент к объекту обращается только один поток, у вас есть гарантия, что каждый метод завершится до того, как будет вызван следующий метод. Это значит, что для своих клиентов объект всегда пребывает в действительном состоянии. Однако когда несколько потоков работают одновременно, вы легко можете получить ситуации, в которых процессор переключается на другой поток, в то время как ваш объект находится в недействительном состоянии. Если затем этот поток также попытается использовать этот же объект, результат будет совершенно непредсказуем. Поэтому термин "безопасность потоков" означает постоянное поддержание членов объекта в действительном состоянии при их одновременном использовании несколькими потоками.
Как избежать подобных непредсказуемых состояний? Для этого можно использовать стандартное средство — синхронизация. Синхронизация позволяет задавать критические секции (critical sections) кода, в которые в каждый отдельный момент может входить только один поток, гарантируя, что любые временные недействительные состояния объекта будут невидимы его клиентам. Имеется несколько средств определения критических секций, включая классы .NET Monitor и Mutex, а также оператор С# lock.
Формат использования инструкции lock таков:
lock(выражение) {
// Инструкции, подлежащие синхронизации.
}
Для обычных методов в качестве выражения используется указатель this, для статических – typeof(класс).
Здесь параметр выражение представляет собой ссылку на синхронизируемый объект. Если нужно синхронизировать только один элемент, фигурные скобки можно опустить. Инструкция lock гарантирует, что указанный блок кода, защищенный блокировкой для данного объекта, может быть использован только потоком, который получает эту блокировку. Все другие потоки остаются заблокированными до тех пор, пока блокировка не будет снята. А снята она будет лишь при выходе из этого блока.
Синхронизация доступа к общим данным с помощью блокировок.
Задание: 1) Проанализировать процесс синхронизации посредством управления доступом к методу sumIt(), который суммирует элементы массива целочисленного типа, используя инструкцию блокировки lock(this) и без нее:
class SumArray
{ int sum; public int sumIt(int[] mas) {
//lock (this)//Блокировка всего метода //{
sum = 0;
for (int i = 0; i < mas.Length; i++)
{ sum += mas[i];
Console.WriteLine("Промежуточная сумма для потока " + Thread.CurrentThread.Name + "=" + sum);
Thread.Sleep(50); }
return sum;
//}} }//////////////////////////////////////////////////////////////////
class SThread
{public Thread Thrd; int[] array; int rezult;
//Создаем один объект класса SumArray //для всех экземпляров класса SThread (для всех потоков):
static SumArray Ob_sum = new SumArray();
//Конструктор для создания нового потока:
public SThread(string name, int[] mas)
{ array = mas;//Объекты одного типа (массивы это объекты)можно присваивать друг другу.
Thrd = new Thread(new ThreadStart(this.run));Thrd.Name = name;
Thrd.Start();//Запускаем поток на выполнение
}
// Начало выполнения нового потока:
void run() { Console.WriteLine(Thrd.Name + " стартовал."); rezult = Ob_sum.sumIt(array);
Console.WriteLine("Сумма для потока " + Thrd.Name + "=" + rezult);
Console.WriteLine("Поток " + Thrd.Name + " завершен!"); } }
/////////////////////////////////////////////////////////////
class Sync{static void Main(string[] args) { int[] mas ={ 1, 2, 3, 4, 5 };
SThread MyT1 = new SThread("Потомок №1", mas);
SThread MyT2 = new SThread("Потомок №2", mas);
//Метод Join сообщает системе, что приложение должно ожидать завершения потока.
MyT1.Thrd.Join(); MyT2.Thrd.Join();}}
