Опубликован: 23.01.2013 | Уровень: для всех | Доступ: платный | ВУЗ: Томский политехнический университет
Самостоятельная работа 1:

Создание первого приложения

< Лекция 2 || Самостоятельная работа 1 || Лекция 3 >
Аннотация: В данном практическом занятии, будет создано простое многопоточное приложение, в котором будет реализовано три различных потока.

  1. Создадим простое консольное приложение и назовем его, к примеру, "SImpleMultithreadingApplication":
  2. Далее выведем в однопоточном режиме сообщение "Hello World!" с помощью кода:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    namespace SimpleMultithreadingApplication
    {
        class Program
        {
            static void Main(string[] args)
            {
                for (int i = 0; i < 10;i++)
                {
                    Console.WriteLine("Hello World!");
                }
       Console.ReadLine();
            }
        }
    }

    Так как, действие выполняется в один поток (метод Main), результат будет следующим:

  3. Для того, что бы использовать многопоточность, используем директиву System.Threading:
    using System.Threading;
  4. Теперь, создадим три различных метода, которые будут выполняться в различных потоках:
    static void FirstThread()
            {
                for (int i=0;i<10;i++)
                {
                    Console.WriteLine("Первый поток говорит: Hello!");
                }
            }
            static void SecondThread()
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("Второй поток говорит: World!");
                }
            }
            static void ThirdThread()
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("Третий поток говорит: Hello World!");
                }
            }
  5. В методе Main создаем потоки:
    Thread thread1 = new Thread(new ThreadStart(FirstThread))
    Thread thread2 = new Thread(new ThreadStart(SecondThread))
    Thread thread3 = new Thread(new ThreadStart(ThirdThread))

    В нашем случае поток:

    • thread1 - вызывает метод FirstThread
    • thread2 - вызывает метод SecondThread
    • thread3 - вызывает метод ThirdThread
  6. Запускаем потоки, с помощью метода Start():
                thread1.Start()
                thread2.Start()
                thread3.Start()
  7. Добавим на вывод в главном потоке (метод Main), следующие строчки:
    Console.WriteLine("Главный поток молчит")
                Console.WriteLine("Завершение главного потока")
                Console.ReadLine()

    Весь код будет выглядеть следующим образом:

    static void Main(string[] args)
           {
                Thread thread1 = new Thread(new ThreadStart(FirstThread));
                Thread thread2 = new Thread(new ThreadStart(SecondThread));
                Thread thread3 = new Thread(new ThreadStart(ThirdThread));
                thread1.Start();
                thread2.Start();
                thread3.Start();
                Console.WriteLine("Главный поток молчит");
                Console.WriteLine("Завершение главного потока");
                Console.ReadLine();
            }
  8. Запустим приложение. Результат будет следующим:

    Как видно из результата, потоки выполняются с различным интервалом по времени.

  9. Для того, что бы задать время блокировки, на выполнение потока, используем метод Sleep(). Для главного потока установим время блокировки 1000мс:
    Thread.Sleep(1000)
    Console.WriteLine("Главный поток молчит")
    Console.WriteLine("Завершение главного потока")
    Console.ReadLine()
  10. Аналогично, установим время блокировки, для дочерних потоков 20мс, 100мс, 90мс:
    static void FirstThread()
            {
                for (int i=0;i<10;i++)
                {
                  Thread.Sleep(20);
                    Console.WriteLine("Первый поток говорит: Hello!");
                }
               Console.WriteLine("Завершение первого потока");
            }
            static void SecondThread()
            {
                for (int i = 0; i < 10; i++)
                {
                    Thread.Sleep(100);
                    Console.WriteLine("Второй поток говорит: World!");
                }
              Console.WriteLine("Завершение второго потока");
            }
            static void ThirdThread()
            {
                for (int i = 0; i < 10; i++)
                {
                 Thread.Sleep(90);
                    Console.WriteLine("Третий поток говорит: Hello World!");
                }
               Console.WriteLine("Завершение третьего потока");
            }
  11. Запустим программу. Результат будет следующим:

    Как видно из результата выполнения программы: первый поток завершится первым, т.к время блокировки составляет 20мс. Второй и третий поток будут выполняться почти одновременно, т.к время блокировки составляет 90мс и 100мс. Второй поток и главный поток завершатся почти одновременно т.к общее время блокировки второго и главного потока составляет 1000мс.

    Листинг кода программы:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    using System.Collections.Concurrent;
    namespace ConcurrentCollectionsApplication
    {
        class Program
        {
            static BlockingCollection<char> bc;
            static void Producer()
            {
                for (char ch = 'А'; ch <= 'Я'; ch++)
                {
                    bc.Add(ch);
                    Console.WriteLine("Производится символ " + ch);
                }
           bc.CompleteAdding();
            }
            static void Consumer()
            {
                char ch;
                
                    while(!bc.IsCompleted)
                   {
                 if(bc.TryTake(out ch))
                    Console.WriteLine("Потребляется символ "+bc.Take());
                    }
                
            }
            static void Main(string[] args)
            {
                bc = new BlockingCollection<char>(4);
                Task Prod = new Task(Producer);
                Task Con = new Task(Consumer);
                Con.Start();
                Prod.Start();
                try
                {
                    Task.WaitAll(Con, Prod);
                }
                catch (AggregateException exc)
                {
                    Console.WriteLine(exc);
                }
                finally
                {
                    Con.Dispose();
                    Prod.Dispose();
                    bc.Dispose();
                }
                Console.ReadLine();
            }
        }
    }
< Лекция 2 || Самостоятельная работа 1 || Лекция 3 >
Владимир Каширин
Владимир Каширин

Вопрос по Курсу: "Параллельное программирование с использованием MS VisualStudia 2010".

При компиляции Самостоятельного задания (одновременная отрисовка прямоугольников, эллипсов и выдача в текст-бокс случайного числа) среда предупреждает: suspend - устаревшая команда; примените monitor, mutex и т.п.

Создаётся впечатление, что Задание создано в более поздней среде, чем VS 2010.

Александр Гаврилов
Александр Гаврилов
Россия
Роман Дмитриев
Роман Дмитриев
Россия, Москва