Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как ускорить работу кода? / 25 сообщений из 27, страница 1 из 2
08.07.2014, 18:06
    #38690946
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Существует проект(написан еще до меня на C#).
загружается фотография(работает фоном).
По размеру фотографии поелементно создается матрица 20x20 из UserControl-компонентов.

на компоненте:
public System.Windows.Forms.Panel pnMain;
public System.Windows.Forms.Label lblText;

Очень долго загружается(у меня проц і5, а на производстве вообще мрак)

Как ускорить работу кода?
Можно переписать код, но принцып изменить немугу, там завязано много на этот принцып.
Код процедуры:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
public static void CreateSections(PictureBox pbMain, IDictionary<string, string> dic, int cellCountRows = 20, int cellCountColumns =20 ) {
	Size sz = getZoomedImage(pbMain);

	double width = sz.Width;
	double height = sz.Height;

	if (width % 10 > 0)
		width = Math.Round(width / 10) * 10;

	if (height % 10 > 0)
		height = Math.Round(height / 10) * 10;

	float widthOneComponent = sz.Width / cellCountColumns;
	float heightOneComponent = sz.Height / cellCountRows;

	int v_begin = (pbMain.ClientSize.Height - sz.Height) / 2;
	int h_begin = (pbMain.ClientSize.Width - sz.Width) / 2;

	int v = v_begin;
	int h = h_begin;
	
	int number = 1;
	pbMain.Visible = false;

	while ((v + heightOneComponent - (heightOneComponent / 2)) < (height + v_begin)) {
		
		while ((h + widthOneComponent - (widthOneComponent / 2)) < (width + h_begin)) {
			Cell r = new Cell();
			r.Name = "VisComponent" + number;
			r.Top = v;
			r.Left = h;
			r.Height = Convert.ToInt32(heightOneComponent);
			r.Width = Convert.ToInt32(widthOneComponent);

			r.pnMain.Click += delegate(object o, EventArgs e) {
				using (SqlConnection con = new SqlConnection(ConnStr)) {
					r.lblText.Visible = true;
					r.lblText.ForeColor = Color.Red;
					r.lblText.BackColor = Color.Red;

					con.Open();
					string sql = " insert into tbl_Transaction(AssmID, Position, LastUpdate) " +
									" values(@AssmID, @Position, GETDATE()) ";
					using (SqlCommand com = new SqlCommand(sql, con)) {
						com.Parameters.Add("@AssmID", dic["id"]);
						com.Parameters.Add("@Position", r.lblText.Text);
						com.ExecuteNonQuery();
					}
				}

				System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
				timer.Interval = 1000;
				timer.Tick += (source, u) => { r.lblText.Visible = false; timer.Stop(); };
				timer.Start();
			};

			r.BorderStyle = BorderStyle.None;
			r.lblText.Text = number.ToString();
			r.lblText.Left = 0;
			r.lblText.Top = 0;
			r.lblText.ForeColor = Color.White;
			r.lblText.BackColor = Color.Black;
			r.lblText.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			//-----
			r.lblText.Visible = false;

			pbMain.Controls.Add(r);

			number += 1;
			h += Convert.ToInt32(widthOneComponent);
		}
		
		v += Convert.ToInt32(heightOneComponent);
		h = 0;
		
	}

	pbMain.Visible = true;
}


Спасибо за внимание!
...
Рейтинг: 0 / 0
08.07.2014, 18:39
    #38691005
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
нечего тут оптимизировать... может ежли только не pbMain.Controls.Add(r); а сперва создать массив и вкрячить его в конце через pbMain.Controls.AddRange(...)

И delegate(object o, EventArgs e) {
...
};

Опишите отдельно... просто громоздко... как-то...
...
Рейтинг: 0 / 0
08.07.2014, 19:00
    #38691027
petalvik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
SNenko,

O_O
Жуть! 400 запросов к БД!
На каждой итерации таймер создаётся и запускается...


Частично можно оптимизировать, если создать все используемые контролы один раз, например, при запуске программы. То есть сделать их полями, а не локальными переменными.

Должен быть всего один запрос к БД.

Возможно, чуть помогут вызовы методов SuspendLayout() и ResumeLayout() в начале и конце соответственно.
...
Рейтинг: 0 / 0
08.07.2014, 19:02
    #38691030
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
SNenko,

20x20 из UserControl-компонентов - выбросить нахер компоненты

тексты и фон рисовать поверх картинки , клики мыши отрабатывать на картинке.
...
Рейтинг: 0 / 0
08.07.2014, 19:04
    #38691031
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
petalvikЖуть! 400 запросов к БД!
На каждой итерации таймер создаётся и запускается...


не на итерации, а по клику
...
Рейтинг: 0 / 0
08.07.2014, 19:05
    #38691033
petalvik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
А, таймер по клику запускается. Сразу не разглядел.
...
Рейтинг: 0 / 0
08.07.2014, 20:40
    #38691113
bazile
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
SNenko, поставь вместо pbMain.Visible = false; вызов pbMain.SuspendLayout();
А вместо pbMain.Visible = true; соответственнно вызов pbMain.ResumeLayout();

Также следует избавиться от анонимной функции и заменить её на обычную функцию. В коде используется захват локальной переменной r. Чтобы код откомпилировался нужно добавить в начале функции следующую строку:
Код: c#
1.
Cell r = (Cell)(((Control)o).Parent);


Здесь предполагается что Cell является родителем для кнопки. Если есть еще один или несколько уровней вложенности, то не составит труда написать extension функцию FindParent<T> для класса Control которая найдет родителя нужного типа.
...
Рейтинг: 0 / 0
09.07.2014, 04:31
    #38691310
Василий Викторович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
SNenko,

1) разделение логики и интерфейса, вспоминаем парадигму MVC, т. е. посреди настройки внешнего вида не должен быть код работающий с данными
2) вынести sql в отдельную процедуру на ms sql сервер -> оптимизация sql кода, пайджинг на стороне ms sql server'a и все такое
3) 2 сторонний databinding на основе механизмов NET

После этого можно подумать дальше
...
Рейтинг: 0 / 0
09.07.2014, 07:28
    #38691333
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Василий ВикторовичSNenko,

1) разделение логики и интерфейса, вспоминаем парадигму MVC, т. е. посреди настройки внешнего вида не должен быть код работающий с данными
2) вынести sql в отдельную процедуру на ms sql сервер -> оптимизация sql кода, пайджинг на стороне ms sql server'a и все такое
3) 2 сторонний databinding на основе механизмов NET

После этого можно подумать дальше
Все бы ничего, только к коду топикстартера это имеет мало отношения
...
Рейтинг: 0 / 0
09.07.2014, 07:55
    #38691349
Василий Викторович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Изопропил,

Вот мне интересно откуда вы взяли что эти рекомендации не помогут? как минимум я тут вижу код требующий рефакторинга, правда истинное название этого немного другое ну да ладно,
1) MVC - причины: котлеты отдельно мухи отдельно, т. е. разнести как минимум настройку интерфейса и обращение к БД в 2 разные функции, именно функции а не реализованный в середине функции анонимный делегат
2) Sql, голый sql запрос выдает с головой уровень писавшего это, как минимум обвернуть это в хранимую процедуру и ее дергать о технологиях ОRM и иже с ними я промолчу, о пайдженге на стороне сервера чтобы не тянуть тысячи записей тоже
3) ручное создание ячеек как минимум дурно пахнет так как уже давным - давно применяют DataBindings колекций обьектов к элементам интерфейса причем биндинг является двух сторонним со всякими интересными плюшками в виде генераций подтаблиц и валидаторов пользовательского ввода

P. S. код - результат человека только начавшего делать первые шаги в освоении языка и по этому допускающего определенные детские промахи, это исправимо, года через 1,5 после того как наберется опыта
...
Рейтинг: 0 / 0
09.07.2014, 08:26
    #38691373
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Василий ВикторовичВот мне интересно откуда вы взяли что эти рекомендации не помогут?
Вы, не читая кода, дали абстрактные советы

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

достаточно рисовать текст непосредственно поверх картинки и клики отрабатывать на картинке
...
Рейтинг: 0 / 0
09.07.2014, 10:07
    #38691488
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Говоря о мухах и котлаетах, вы безусловно правы.

Почищу код и выложу результат
...
Рейтинг: 0 / 0
09.07.2014, 15:32
    #38692055
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Быстрее работать не стало, но уменьшилось количество неточностей.

Щас закину в масив. Использу pbMain.Controls.AddRange(...).
Но это для порядка.
Не думаю что поможет..
Буду делать обработку кликов на картинке pbMain.
Спасибо за советы.

Выложу потом следюущий код.

это процедура:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public static void CreateSections(PictureBox pbMain, IDictionary<string, string> dic, int cellCountRows = 20, int cellCountColumns =20 )
{
	pbMain.SuspendLayout();
	
	MyImage image = new MyImage(pbMain);
	MyCell cell = new MyCell(image, cellCountRows, cellCountColumns);
	MyCurrentCellPosition curr = new MyCurrentCellPosition(image, cell);
	
	for (int y = 1; y <= cellCountRows; y++)
	{
		for (int x = 1; x <= cellCountColumns; x++)
		{
			Cell r = new Cell(x*y, curr.y, curr.x, cell.size, dic["id"], ConnStr);
			pbMain.Controls.Add(r);
			curr.NewCell();
		}
		curr.NewRow();
	}
	pbMain.ResumeLayout();
}


А это класы к ней:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
        class MyImage
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
            public Size size;

            public MyImage(PictureBox pbMain)
            {
                this.size = getZoomedImage(pbMain);
                this.Left = (pbMain.ClientSize.Width - size.Width) / 2;
                this.Top = (pbMain.ClientSize.Height - size.Height) / 2;
                generate_RightBottom();
                rounding();
            }
            
            private void generate_RightBottom()
            {
                this.Right = this.Left + this.size.Width;
                this.Bottom = this.Top + this.size.Height;
            }
            private void rounding()
            {
                size.Width = takeTenPercent(size.Width);
                size.Height = takeTenPercent(size.Height);
            }
            private int takeTenPercent(int value)
            {
                if (value % 10 > 0)
                    return Convert.ToInt32(Math.Round((double)value / 10) * 10);
                return value;
            }
            //get size of image after zoom in picturebox
            private static Size getZoomedImage(PictureBox pictureBox1)
            {
                float x = pictureBox1.ClientSize.Width; // Ширина клиентской области
                float y = pictureBox1.ClientSize.Height; // Высота клиентской области

                float z1 = pictureBox1.Image.Width; //Ширина загруженного изображения
                float z2 = pictureBox1.Image.Height; //Высота загруженного изображения

                float q;  // Коэффициент
                float q1; //Отмасштабированная ширина
                float q2; //Отмасштабированная высота

                if (z1 > x | z2 > y)
                {
                    if (z1 > z2)  // z1>x
                    {
                        q = z1 / x;//коофіцієнт = восота зобр/ висота блоку

                        q1 = z1 / q;
                        q2 = z2 / q;
                        if (q2 > y)
                        {
                            q = z2 / y;
                            q1 = z1 / q;
                            q2 = z2 / q;
                            return new Size((int)q1, (int)q2);
                        }
                        else
                        {
                            return new Size((int)q1, (int)q2);
                        }
                    }
                    if (z2 > z1)  // z2>y
                    {
                        q = z2 / y;
                        q1 = z1 / q;
                        q2 = z2 / q;
                        if (q1 > x)
                        {
                            q = z1 / x;
                            q1 = z1 / q;
                            q2 = z2 / q;
                            return new Size((int)q1, (int)q2);
                        }
                        else
                        {
                            return new Size((int)q1, (int)q2);
                        }
                    }
                }
                return new Size((int)z1, (int)z2);
            }

        }

        class MyCell
        {
            public Size size;

            public MyCell(MyImage image, int cellCountRows, int cellCountColumns)
            {
                this.size = new Size(Convert.ToInt32(image.size.Width / cellCountColumns), Convert.ToInt32(image.size.Height / cellCountRows));
            }
        }

        class MyCurrentCellPosition
        {
            MyImage image;
            public int x;
            public int y;

            public MyCell cell;

            public MyCurrentCellPosition(MyImage image, MyCell cell)
            {
                this.x = image.Left;
                this.y = image.Top;
                this.image = image;
                this.cell = cell;
            }

            public void NewRow()
            {
                this.y += cell.size.Height;
                this.x = image.Left;
            }

            public void NewCell()
            {
                this.x += cell.size.Width;
            }
        }


...
Рейтинг: 0 / 0
09.07.2014, 16:06
    #38692119
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Нащет скорости обработки ошибся.
Если использовать pbMain.Controls.AddRange(cells), обработка ускоряется раза в полтора.


предыдущий вариант(с класами): 2756 микросекунд
используя AddRange : 1110 микросекунд

но это всеравно много..

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
public static void CreateSections(PictureBox pbMain, IDictionary<string, string> dic, int cellCountRows = 20, int cellCountColumns =20 )
{
	MyImage image = new MyImage(pbMain);
	MyCell cell = new MyCell(image, cellCountRows, cellCountColumns);
	MyCurrentCellPosition curr = new MyCurrentCellPosition(image, cell);
	
	Cell[] cells = new Cell[401];
	for (int y = 1; y <= cellCountRows; y++)
	{
		for (int x = 1; x <= cellCountColumns; x++)
		{
			int number = x * y;
			cells[number] = new Cell(number, curr.y, curr.x, cell.size, dic["id"], ConnStr);
			curr.NewCell();
		}
		curr.NewRow();
	}
	pbMain.SuspendLayout();
	pbMain.Controls.AddRange(cells);
	pbMain.ResumeLayout();
}




Дело в том, что во время AddRange(как и в предыдущей поэлементной загрузке), изображение загружается кубиками.
Это при условиях:
pbMain.Visible=false;
pbMain.SuspendLayout();
...
Рейтинг: 0 / 0
09.07.2014, 17:18
    #38692210
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
SNenko,

контролы то зачем нужны? клик ловить и текстовое сообщение показывать?
...
Рейтинг: 0 / 0
10.07.2014, 10:26
    #38692764
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Изопропил,
Так до меня было. Поэтому, я изменяю по-этапно.
Думаю, lblText, вообще можно убрать, заменив простой переменной.

Это конструкто класа Cell:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
        public Cell(int number, int Top, int Left, Size size, string dic_id, string ConnStr)
        {
            InitializeComponent();
            this.Name = "VisComponent" + number.ToString();
            this.Top = Top;
            this.Left = Left;
            this.lblText.Text = number.ToString();
            this.Size = size;

            this.lblText.Size = this.Size;
            this.pnMain.Size = this.Size;

            
            this.pnMain.Click += delegate(object o, EventArgs e)
            {

                using (SqlConnection con = new SqlConnection(ConnStr))
                {
                    this.lblText.Visible = true;
                    this.lblText.ForeColor = Color.Red;
                    this.lblText.BackColor = Color.Red;

                    con.Open();
                    string sql = " insert into tbl_Transaction(AssmID, Position, LastUpdate) " +
                                    " values(@AssmID, @Position, GETDATE()) ";
                    using (SqlCommand com = new SqlCommand(sql, con))
                    {
                        com.Parameters.Add("@AssmID", dic_id);
                        com.Parameters.Add("@Position", this.lblText.Text);
                        com.ExecuteNonQuery();
                    }
                }

                System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
                timer.Interval = 1000;
                timer.Tick += (source, u) => { this.lblText.Visible = false; timer.Stop(); };
                timer.Start();
            };
        }

...
Рейтинг: 0 / 0
10.07.2014, 10:46
    #38692797
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
К стати, выяснилось, что в два раза быстрее оно работает, потомучто размещает в два раза меньше компонентов.
Даже незнаю куда они с масива деваются.(картинка выше)
...
Рейтинг: 0 / 0
10.07.2014, 10:56
    #38692807
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
SNenko,

я правильно понимаю, что по клику нужно сделать запись в базу на секунду нарисовать красный прямоугольник?
...
Рейтинг: 0 / 0
10.07.2014, 11:05
    #38692824
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
ИзопропилSNenko,

я правильно понимаю, что по клику нужно сделать запись в базу на секунду нарисовать красный прямоугольник?
Именно так.
...
Рейтинг: 0 / 0
10.07.2014, 11:06
    #38692827
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
SNenkoК стати, выяснилось, что в два раза быстрее оно работает, потомучто размещает в два раза меньше компонентов.
Даже незнаю куда они с масива деваются.(картинка выше)
Тут моя ошибка я умножал: х*у.
надо было просто number++;
...
Рейтинг: 0 / 0
10.07.2014, 11:10
    #38692838
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Получается, что поэлементно и массивом оно заносит почти одинаково(разница на 100 микросекунд).
Я думаю, что много времени занимает поэлементная прорисовка.
Незнаю как ее отключить..
Во всяком случае, код стал более читабелен(для меня)

Приступлю к варианту с кликами на bictureBox. Тоесть, без масива, а с прорисовкой конкретного килика.
...
Рейтинг: 0 / 0
10.07.2014, 12:03
    #38692932
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
SNenkoПриступлю к варианту с кликами на bictureBox. Тоесть, без масива, а с прорисовкой конкретного килика.
правильный путь.

потребуется одна панель, на ней рисуется картинка и закрашиваются прямоугольники
и никаких лишних контролов
...
Рейтинг: 0 / 0
10.07.2014, 14:31
    #38693245
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Изопропил,

Перфоманс Аналайзер вам в помощь, на нём увидите где программа больше всего тормозит и там уже будите думать, как это решить.
...
Рейтинг: 0 / 0
10.07.2014, 15:58
    #38693459
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Roman MejtesИзопропил,

Перфоманс Аналайзер вам в помощь, на нём увидите где программа больше всего тормозит и там уже будите думать, как это решить.


Господа теоретики, не нужна мне помощь, я читать код умею.
Да и задачка не у меня.

В данном случае - тормоза на беспощадном и бессмысленном создании сотен windows контролов.
Несчастный обработчик клика мыши - не нуждается в оптимизации. Если только с эстетической точки зрения
...
Рейтинг: 0 / 0
10.07.2014, 16:17
    #38693510
SNenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как ускорить работу кода?
Roman MejtesИзопропил,

Перфоманс Аналайзер вам в помощь, на нём увидите где программа больше всего тормозит и там уже будите думать, как это решить.
я пользуюсь своим класом.
Но спасибо Вам за совет!

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
public class SW : Stopwatch
{
	public SW()
	{
		this.Start();
	}

	public void write(string text)
	{
		if (this.IsRunning)
		{
			this.Stop();
			Console.WriteLine("{0} (час: {1})", text, this.ElapsedMilliseconds);
			//--Console.WriteLine("{0} (час: {1})", text, this.Elapsed);
			this.Reset();
		}
		else
			Console.WriteLine("{0}", text);
		this.Start();
	}
}
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как ускорить работу кода? / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]