Exemple #1
0
        static void Main(string[] args)
        {
            #region Threading
            var threading = new Threading();
            // Потоки для асинхронных вычислительных операций
            Console.WriteLine("Main thread: starting a dedicated thread " + "to do an asynchronous operation");
            Thread dedicatedThread = new Thread(ComputeBoundOp);
            dedicatedThread.Start(5);
            Console.WriteLine("Main thread: Doing other work here...");
            Thread.Sleep(10000);    // Имитация другой работы (10 секунд)
            dedicatedThread.Join(); // Ожидание завершения потока
            Console.WriteLine("Hit <Enter> to end this program...");

            /*
             *  Результат компиляции и запуска такого кода:
             *  Main thread: starting a dedicated thread to do an asynchronous operation
             *  Main thread: Doing other work here...
             *  In ComputeBoundOp: state=5
             *
             *  Так как мы не можем контролировать очередность исполнения потоков
             *  в Windows, возможен и другой результат:
             *  Main thread: starting a dedicated thread to do an asynchronous operation
             *  In ComputeBoundOp: state=5
             *  Main thread: Doing other work here...
             */

            // Фоновые и активные потоки
            // Создание нового потока (по умолчанию активного)
            Thread t = new Thread(Worker);
            // Превращение потока в фоновый
            t.IsBackground = true;
            t.Start(); // Старт потока
                       // В случае активного потока приложение будет работать около 10 секунд
                       // В случае фонового потока приложение немедленно прекратит работу
            Console.WriteLine("Returning from Main");

            // Простые вычислительные операции
            Console.WriteLine("Main thread: queuing an asynchronous operation");
            ThreadPool.QueueUserWorkItem(ComputeBoundOp, 5);
            Console.WriteLine("Main thread: Doing other work here...");
            Thread.Sleep(10000); // Имитация другой работы (10 секунд)
            Console.WriteLine("Hit <Enter> to end this program...");

            /*
             *  Результат компиляции и запуска этого кода:
             *  Main thread: queuing an asynchronous operation
             *  Main thread: Doing other work here...
             *  In ComputeBoundOp: state=5
             *
             *  Впрочем, возможен и такой результат:
             *  Main thread: queuing an asynchronous operation
             *  In ComputeBoundOp: state=5
             *  Main thread: Doing other work here...
             *
             *  Разный порядок следования строк в данном случае объясняется асинхронным
             *  выполнением методов. Планировщик Windows решает, какой поток должен выполняться первым, или же планирует их для одновременного выполнения на
             *  многопроцессорном компьютере
             */

            // Контексты исполнения
            // Помещаем данные в контекст логического вызова потока метода Main
            CallContext.LogicalSetData("Name", "Jeffrey");
            // Заставляем поток из пула работать
            // Поток из пула имеет доступ к данным контекста логического вызова
            ThreadPool.QueueUserWorkItem(state => Console.WriteLine("Name={0}", CallContext.LogicalGetData("Name")));
            // Запрещаем копирование контекста исполнения потока метода Main
            ExecutionContext.SuppressFlow();

            // Заставляем поток из пула выполнить работу.
            // Поток из пула НЕ имеет доступа к данным контекста логического вызова
            ThreadPool.QueueUserWorkItem(state => Console.WriteLine("Name={0}", CallContext.LogicalGetData("Name")));
            // Восстанавливаем копирование контекста исполнения потока метода Main
            // на случай будущей работы с другими потоками из пула
            ExecutionContext.RestoreFlow();

            // Скоординированная отмена
            threading.CoordinatedCancel();

            // Задания
            ThreadPool.QueueUserWorkItem(ComputeBoundOp, 5); // Вызов QueueUserWorkItem
            new Task(ComputeBoundOp, 5).Start();             // Аналог предыдущей строки
            Task.Run(() => ComputeBoundOp(5));               // Еще один аналог

            // Завершение задания и получение результата
            threading.EndTask();

            // Отмена задания
            threading.CancelTask();

            // Автоматический запуск задания по завершении предыдущего
            threading.RunTaskAfterEndPrevious();
            threading.RunTaskAfterEndPrevious2();

            // Дочерние задания
            threading.ChildTasks();

            // Планировщики заданий - сделать приложение WPF/Winforms

            // Parallel LINQ

            // Периодические вычислительные операции

            // События
            threading.Events();

            // Блокировка с двойной проверкой
            String name = null;
            // Так как имя равно null, запускается делегат и инициализирует поле имени
            LazyInitializer.EnsureInitialized(ref name, () => "Jeffrey");
            Console.WriteLine(name); // Выводится "Jeffrey"
                                     // Так как имя отлично от null, делегат не запускается и имя не меняется
            LazyInitializer.EnsureInitialized(ref name, () => "Richter");
            Console.WriteLine(name); // Снова выводится "Jeffrey"
            #endregion

            Console.ReadLine();
        }