Вернуться   D3Scene.Ru Софт портал игр | Хаки | Проги | Статьи > Другое > Информационные технологии > Программирование > С++/C#
Присоединяйся к нам



Ответ
 
Опции темы Опции просмотра
Старый 04.10.2010, 21:37   #1
Lost


 
Аватар для N.e.o.
 
Регистрация: 20.08.2009
Адрес: Matrix
Сообщений: 1,028
Репутация: 802
Автор Сообщение

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


Давайте создать многопоточную программу.


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

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

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


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

в библиотеки подключаем:
Цитата:
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;
подключили, идем дальше. Нам надо сделать первую анимацию, для етого будем использовать контрол ImageList. Перетаскиваем на форму с toolbox-а 3 ImageList-а (всего будет 3 анимации). Заодно перетаскиваем ToolStrip (меню на верху приложения в виде кнопочок ) первая кнопка - запуск 1 анимации, вторая - второй...

Переходм к самому написанию кода.
Надо создать 3 графика чтоби отображать их. Если надо, нет проблем - создаем Заодно создадим 3 булевских переменних, потом поймем зачем
Цитата:
Graphics theGraphics1;
Graphics theGraphics2;
Graphics theGraphics3;
Graphics theGraphics3;
bool firstImgMove = false;
bool secondImgMove = false;
bool thirdImgMove = false;
дальше идем в конструктор класа нашего окна. В нем ми добавим картинки в нашие имиджЛисти, зададим им размер и передадим трем графикам хендл главного окна для дальнейшего отображения.

Цитата:
public Form1()
{
InitializeComponent();
theGraphics1 = Graphics.FromHwnd(this.Handle);
theGraphics2 = Graphics.FromHwnd(this.Handle);
theGraphics3 = Graphics.FromHwnd(this.Handle);
//----------- достаем обєкт Graphics из хендла форми
imageList1.ImageSize = new Size(256, 120);//размер 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(206, 256);
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(207, 256);
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 имиджлист
}
теперь создадим ф-цию которая будет из 1 набора картинок делать анимацию. сделаем ее так, если она била б одна:

Цитата:
private void firstAnim()
{

while (firstImgMove)//становится true после нажатия на 1 кнопку тулСтрип-та
{
i = i + 4;//изменяем положение каждий раз
for (int count = 0; count < imageList1.Images.Count; count++)
{
imageList1.Draw(theGraphics1, new Point(i, 40), count);
Application.DoEvents();
System.Threading.Thread.Sleep(80);
//ето наше слайдшоу с задержкой 80милисекунд.
}
if (i > 350)
{
i = 10;
Invalidate();
//если вишло за рамки картинки, начинаем сначала.
}
}
}
ф-ция запускается когда firstImgMove = true на для начала надо обработать клик на 1 кнопку тулСтрип-та что надо запустить 1 анимацию(визвать firstAnim())
Цитата:
private void toolStripButton1_Click(object sender, EventArgs e)
{
firstImgMove = true;
firstAnim();
}
запустили 1 анимацию, все ок. хотим запустить вторую. и тут у нас проблема...
когда пригает нашая первая анимация наша програма занята ее рисованием, и ми не сможем (если очень захотеть то сможем то трудно)) ) запустить паралельно вторую... для етого ми создадим новий поток, но для начала напишем ф-цию анимирования 2 анимации и обработаем ее запуск при клике на 2 кнопку.
Цитата:
private void secondAnim()
{

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

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

теперь создадим еще один для 3 анимации и обработаем клик на 3 кнопку нашего меню:
Цитата:
private void thirdAnim()
{

while (thirdImgMove)
{
for (int count = 0; count < imageList3.Images.Count; count++)
{
imageList3.Draw(theGraphics3, new Point(50, 180), count);
Application.DoEvents();
System.Threading.Thread.Sleep(300);
}
}
}
private void toolStripButton3_Click(object sender, EventArgs e)
{
thirdImgMove = true;
Thread t2 = new Thread(thirdAnim);//создаем еще один поток для ф-ции thirdAnim
t2.Start();//запускаем поток
}
теперь давайте еще сделаем возможность остановить любую анимацию.
для етого создадим контекстное меню (откривается при клике правой кнопкой). перетаскиваем из тулбокса ContextMenuStrip и в параметрах нашей форми ставим в "ContextMenuStrip" contextMenuStrip1. додаем пункти в меню Stop 1/ Stop 2/ Stop 3
Обрабативаем клики:
при клике на Stop 1
Цитата:
private void stop1ToolStripMenuItem_Click(object sender, EventArgs e)
{
firstImgMove = false;//смотрим что произойдет в firstAnim()
}
делаем тоде самое для Stop 2
Цитата:
private void stop2ToolStripMenuItem_Click(object sender, EventArgs e)
{
secondImgMove = false;
}
Stop 3
Цитата:
private void stop3ToolStripMenuItem_Click(object sender, EventArgs e)
{
thirdImgMove = false;
}
Теперь когда навести мишку на нашу програму и нажать правую кнопку + например Stop 1 - первая анимация остановится.

И еще один важен момент. Когда ми закриваем програму, надо чтоби нашие ф-ции остановились (оно работают while(firstImgMove), while (secondImgMove) , while (thirdImgMove) ) Для етого обрабативаем собитие FormClosing
Цитата:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
firstImgMove = false;
secondImgMove = false;
thirdImgMove = false;
}
вот и все, готова наша многопоточная анимация
Вот весь код программи:
Цитата:
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(256, 120);
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(206, 256);
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(207, 256);
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)
{
i = i + 4;
for (int count = 0; count < imageList1.Images.Count; count++)
{
imageList1.Draw(theGraphics1, new Point(i, 40), count);
Application.DoEvents();
System.Threading.Thread.Sleep(80);
}
if (i > 350)
{
i = 10;
Invalidate();
}
}
}
private void secondAnim()
{

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

while (thirdImgMove)
{
for (int count = 0; count < imageList3.Images.Count; count++)
{
imageList3.Draw(theGraphics3, new Point(50, 180), count);
Application.DoEvents();
System.Threading.Thread.Sleep(300);
}
}
}


private void stop1ToolStripMenuItem_Click(object sender, EventArgs e)
{
firstImgMove = false;
}


private void stop2ToolStripMenuItem_Click(object sender, EventArgs e)
{
secondImgMove = false;
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
firstImgMove = false;
secondImgMove = false;
thirdImgMove = false;
}


private void stop3ToolStripMenuItem_Click(object sender, EventArgs e)
{
thirdImgMove = false;
}

private void toolStripButton1_Click(object sender, EventArgs e)
{
firstImgMove = true;
firstAnim();
}

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

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

}
}
А готовая программа должна выглядеть так: [Ссылки скрыты от гостей.]

Кликните на для просмотра офф топика

N.e.o. © D3scene.ru
__________________

[Ссылки скрыты от гостей.]
[Ссылки скрыты от гостей.]
По женским представлениям, под покровом темноты мужчины могут думать только о сексе. Это неправда. Днем они тоже о нем думают.*face2*
  Ответить с цитированием Наверх
2 пользователя(ей) сказали cпасибо:
AMG (05.10.2010), Grumpy (05.10.2010)
Старый 16.11.2010, 00:35   #2
Lost


 
Аватар для N.e.o.
 
Регистрация: 20.08.2009
Адрес: Matrix
Сообщений: 1,028
Репутация: 802
Автор По умолчанию

Не туда кинули, ето не с++
__________________

[Ссылки скрыты от гостей.]
[Ссылки скрыты от гостей.]
По женским представлениям, под покровом темноты мужчины могут думать только о сексе. Это неправда. Днем они тоже о нем думают.*face2*
  Ответить с цитированием Наверх
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Powered by vBulletin
Copyright © 2017 vBulletin Solutions, Inc.
Перевод: zCarot | Дизайн: G-A | Верстка: OldEr
Текущее время: 13:41. Часовой пояс GMT +4.