1. Привет Гость, в нашем магазине проходит акция! Смотри эту тему.
    Так же цена на VIP снижена!

[C# урок] Многопоточность

Тема в разделе "Программирование", создана пользователем Бека Алыбаев, 2 дек 2014.

  1. Оффлайн

    Бека Алыбаев System32

    На форуме с:
    28 янв 2013
    Сообщения:
    186
    Симпатии:
    74
    Баллы:
    30
    Пол:
    Мужской
    Давайте создать многопоточную программу.
    Для начала что такое многопоточность:
    PHP:
    Многопото́чность — свойство платформы или приложениясостоящее в томчто процесспорождённый в операционной системеможет состоять из нескольких потоковвыполняющихся «параллельно»то есть без предписанного порядка во времени.
    Наша программа будет состоять из анимации - открытка "Happy Birthday"

    Я заране подготовил картинки которие будут участвовать в анимации.

    Итак начинаем:



    создаем новий проект Windows Forms Application.

    в библиотеки подключаем:

    PHP:
    [SIZE=4]using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading//для многопоточности
    using System.Windows.Forms;[/SIZE]
    подключили, идем дальше. Нам надо сделать первую анимацию, для етого будем использовать контрол ImageList. Перетаскиваем на форму с toolbox-а 3 ImageList-а (всего будет 3 анимации). Заодно перетаскиваем ToolStrip (меню на верху приложения в виде кнопочок ) первая кнопка - запуск 1 анимации, вторая - второй...

    Переходм к самому написанию кода.
    Надо создать 3 графика чтоби отображать их. Если надо, нет проблем - создаем Заодно создадим 3 булевских переменних, потом поймем зачем

    PHP:
    [SIZE=4]Graphics theGraphics1;
    Graphics theGraphics2;
    Graphics theGraphics3;
    Graphics theGraphics3;
    bool firstImgMove false;
    bool secondImgMove false;
    bool thirdImgMove false;[/SIZE]

    дальше идем в конструктор класа нашего окна. В нем ми добавим картинки в нашие имиджЛисти, зададим им размер и передадим трем графикам хендл главного окна для дальнейшего отображения.


    PHP:
    [SIZE=4]public Form1()
    {
    InitializeComponent();
    theGraphics1 Graphics.FromHwnd(this.Handle);
    theGraphics2 Graphics.FromHwnd(this.Handle);
    theGraphics3 Graphics.FromHwnd(this.Handle);
    //----------- достаем обєкт Graphics из хендла форми
    imageList1.ImageSize = new Size(256120);//размер imageList1
    imageList1.Images.Add(Image.FromFile("Frame0.png") );
    imageList1.Images.Add(Image.FromFile("Frame1.png") );
    imageList1.Images.Add(Image.FromFile("Frame2.png") );
    imageList1.Images.Add(Image.FromFile("Frame3.png") );
    imageList1.Images.Add(Image.FromFile("Frame4.png") );
    imageList1.Images.Add(Image.FromFile("Frame5.png") );
    imageList1.Images.Add(Image.FromFile("Frame6.png") );
    //----------- запихаем картинки в 1 имиджлист
    imageList2.ImageSize = new Size(206256);
    imageList2.Images.Add(Image.FromFile("Frame2blackF one.png"));
    imageList2.Images.Add(Image.FromFile("Frame2blackF one2.png"));
    imageList2.Images.Add(Image.FromFile("Frame2blackF one3.png"));
    imageList2.Images.Add(Image.FromFile("Frame2blackF one4.png"));
    //-----------запихаем картинки в 2 имиджлист
    imageList3.ImageSize = new Size(207256);
    imageList3.Images.Add(Image.FromFile("bear00.png") );
    imageList3.Images.Add(Image.FromFile("bear01.png") );
    imageList3.Images.Add(Image.FromFile("bear03.png") );
    imageList3.Images.Add(Image.FromFile("bear04.png") );
    imageList3.Images.Add(Image.FromFile("bear05.png") );
    //-----------запихаем картинки в 3 имиджлист
    }[/SIZE]


    теперь создадим ф-цию которая будет из 1 набора картинок делать анимацию. сделаем ее так, если она била б одна:


    PHP:
    [SIZE=4]private void firstAnim()
    {

    while (
    firstImgMove)//становится true после нажатия на 1 кнопку тулСтрип-та
    {
    4;//изменяем положение каждий раз
    for (int count 0count imageList1.Images.Countcount++)
    {
    imageList1.Draw(theGraphics1, new Point(i40), count);
    Application.DoEvents();
    System.Threading.Thread.Sleep(80);
    //ето наше слайдшоу с задержкой 80милисекунд.
    }
    if (
    350)
    {
    10;
    Invalidate();
    //если вишло за рамки картинки, начинаем сначала.
    }
    }
    }[/
    SIZE]


    ф-ция запускается когда firstImgMove = true на для начала надо обработать клик на 1 кнопку тулСтрип-та что надо запустить 1 анимацию(визвать firstAnim())


    PHP:
    [SIZE=4]private void toolStripButton1_Click(object senderEventArgs e)
    {
    firstImgMove true;
    firstAnim();
    }[/
    SIZE]


    запустили 1 анимацию, все ок. хотим запустить вторую. и тут у нас проблема...
    когда пригает нашая первая анимация наша програма занята ее рисованием, и ми не сможем (если очень захотеть то сможем то трудно)) ) запустить паралельно вторую... для етого ми создадим новий поток, но для начала напишем ф-цию анимирования 2 анимации и обработаем ее запуск при клике на 2 кнопку.



    PHP:
    [SIZE=4]private void secondAnim()
    {

    while (
    secondImgMove)
    {
    for (
    int count 0count imageList2.Images.Countcount++)
    {
    imageList2.Draw(theGraphics2, new Point(300195), count);
    Application.DoEvents();
    System.Threading.Thread.Sleep(300);
    }
    }
    }

    private 
    void toolStripButton2_Click(object senderEventArgs e)
    {
    secondImgMove true;
    Thread t = new Thread(secondAnim);// и вот оно, ми создаем новий поток, которий будет работать паралельно с 1 анимацией и еще одним потоком которий создадим пожже. здесь нам надо указать что наш поток задействует именно ф-цию secondAnim что передаем в конструкторе.
    t.Start();//запускаем поток
    }[/SIZE]


    все, ми создали независимий поток, которий рисует вторую анимацию.

    теперь создадим еще один для 3 анимации и обработаем клик на 3 кнопку нашего меню:


    PHP:
    [SIZE=4]private void thirdAnim()
    {

    while (
    thirdImgMove)
    {
    for (
    int count 0count imageList3.Images.Countcount++)
    {
    imageList3.Draw(theGraphics3, new Point(50180), count);
    Application.DoEvents();
    System.Threading.Thread.Sleep(300);
    }
    }
    }
    private 
    void toolStripButton3_Click(object senderEventArgs e)
    {
    thirdImgMove true;
    Thread t2 = new Thread(thirdAnim);//создаем еще один поток для ф-ции thirdAnim
    t2.Start();//запускаем поток
    }[/SIZE]

    теперь давайте еще сделаем возможность остановить любую анимацию.
    для етого создадим контекстное меню (откривается при клике правой кнопкой). перетаскиваем из тулбокса ContextMenuStrip и в параметрах нашей форми ставим в "ContextMenuStrip" contextMenuStrip1. додаем пункти в меню Stop 1/ Stop 2/ Stop 3
    Обрабативаем клики:
    при клике на Stop 1

    PHP:
    private void stop1ToolStripMenuItem_Click(object senderEventArgs e)
    {
    firstImgMove false;//смотрим что произойдет в firstAnim() 
    }




    делаем тоде самое для Stop 2



    PHP:
    [SIZE=4]private void stop2ToolStripMenuItem_Click(object senderEventArgs e)
    {
    secondImgMove false;
    }[/
    SIZE]


    Stop 3


    PHP:
    [SIZE=4]private void stop3ToolStripMenuItem_Click(object senderEventArgs e)
    {
    thirdImgMove false;
    }[/
    SIZE]


    Теперь когда навести мишку на нашу програму и нажать правую кнопку + например Stop 1 - первая анимация остановится.

    И еще один важен момент. Когда ми закриваем програму, надо чтоби нашие ф-ции остановились (оно работают while(firstImgMove), while (secondImgMove) , while (thirdImgMove) ) Для етого обрабативаем собитие FormClosing



    PHP:
    [SIZE=4]private void Form1_FormClosing(object senderFormClosingEventArgs e)
    {
    firstImgMove false;
    secondImgMove false;
    thirdImgMove false;
    }[/
    SIZE]


    вот и все, готова наша многопоточная анимация
    Вот весь код программи:
    PHP:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;

    namespace 
    program4Animation
    {
    public 
    partial class Form1 Form
    {
    Graphics theGraphics1;
    Graphics theGraphics2;
    Graphics theGraphics3;
    bool firstImgMove false;
    bool secondImgMove false;
    bool thirdImgMove false;
    int i 0;

    public 
    Form1()
    {
    InitializeComponent();
    theGraphics1 Graphics.FromHwnd(this.Handle);
    theGraphics2 Graphics.FromHwnd(this.Handle);
    theGraphics3 Graphics.FromHwnd(this.Handle);
    //-----------
    imageList1.ImageSize = new Size(256120);
    imageList1.Images.Add(Image.FromFile("Frame0.png") );
    imageList1.Images.Add(Image.FromFile("Frame1.png") );
    imageList1.Images.Add(Image.FromFile("Frame2.png") );
    imageList1.Images.Add(Image.FromFile("Frame3.png") );
    imageList1.Images.Add(Image.FromFile("Frame4.png") );
    imageList1.Images.Add(Image.FromFile("Frame5.png") );
    imageList1.Images.Add(Image.FromFile("Frame6.png") );
    //-----------
    imageList2.ImageSize = new Size(206256);
    imageList2.Images.Add(Image.FromFile("Frame2blackF one.png"));
    imageList2.Images.Add(Image.FromFile("Frame2blackF one2.png"));
    imageList2.Images.Add(Image.FromFile("Frame2blackF one3.png"));
    imageList2.Images.Add(Image.FromFile("Frame2blackF one4.png"));
    //-----------
    imageList3.ImageSize = new Size(207256);
    imageList3.Images.Add(Image.FromFile("bear00.png") );
    imageList3.Images.Add(Image.FromFile("bear01.png") );
    imageList3.Images.Add(Image.FromFile("bear03.png") );
    imageList3.Images.Add(Image.FromFile("bear04.png") );
    imageList3.Images.Add(Image.FromFile("bear05.png") );
    }


    private 
    void firstAnim()
    {

    while (
    firstImgMove)
    {
    4;
    for (
    int count 0count imageList1.Images.Countcount++)
    {
    imageList1.Draw(theGraphics1, new Point(i40), count);
    Application.DoEvents();
    System.Threading.Thread.Sleep(80);
    }
    if (
    350)
    {
    10;
    Invalidate();
    }
    }
    }
    private 
    void secondAnim()
    {

    while (
    secondImgMove)
    {
    for (
    int count 0count imageList2.Images.Countcount++)
    {
    imageList2.Draw(theGraphics2, new Point(300195), count);
    Application.DoEvents();
    System.Threading.Thread.Sleep(300);
    }
    }
    }
    private 
    void thirdAnim()
    {

    while (
    thirdImgMove)
    {
    for (
    int count 0count imageList3.Images.Countcount++)
    {
    imageList3.Draw(theGraphics3, new Point(50180), count);
    Application.DoEvents();
    System.Threading.Thread.Sleep(300);
    }
    }
    }


    private 
    void stop1ToolStripMenuItem_Click(object senderEventArgs e)
    {
    firstImgMove false;
    }


    private 
    void stop2ToolStripMenuItem_Click(object senderEventArgs e)
    {
    secondImgMove false;
    }

    private 
    void Form1_FormClosing(object senderFormClosingEventArgs e)
    {
    firstImgMove false;
    secondImgMove false;
    thirdImgMove false;
    }


    private 
    void stop3ToolStripMenuItem_Click(object senderEventArgs e)
    {
    thirdImgMove false;
    }

    private 
    void toolStripButton1_Click(object senderEventArgs e)
    {
    firstImgMove true;
    firstAnim();
    }

    private 
    void toolStripButton2_Click(object senderEventArgs e)
    {
    secondImgMove true;
    Thread t = new Thread(secondAnim);
    t.Start();
    }

    private 
    void toolStripButton3_Click(object senderEventArgs e)
    {
    thirdImgMove true;
    Thread t2 = new Thread(thirdAnim);
    t2.Start();
    }

    }
    }[/
    SIZE]
     
    Последнее редактирование: 2 дек 2014
  2.  

Поделиться этой страницей

Уважаемый пользователь!

Мы обнаружили, что вы блокируете показ рекламы на нашем сайте.

Просим внести его в список исключения или отключить AdBlock.

Наши материалы предоставляются БЕСПЛАТНО и единственным доходом является реклама.

Спасибо за понимание!