Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676

Затык с ООП и динамическими функциями

23.05.2023, 10:07. Показов 736. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сидел я и думал (непривычное занятие) о том, как бы мне модифицировать код с ООП так, чтобы можно было автоматически объекты создавать в нужном количестве просто передавая нужно число в конструктор.
Код рисует массивы на форме по таймеру, и я хочу чтобы если я указал 1, то масштабировался и рисовался на форме один блок, если укажу 8, чтобы было 8 блоков, при этом в идеале конструктору кроме числа блоков хорошо бы отдавать перечень функций, которые будут участвовать в изменении данных каждого блока.
Сейчас это реализации сортировок побайтно.
Код нерабочий по очевидным причинам. Всё что мог запихал в списки. А вот как запихать в списки UpdateData1 и Sort1 я уже не врубаюсь.
Хорошо видно что я в CombSort вызываю отрисовку явно указывая нужную функцию и по сути всё будет кисоваться во втором блоке.
На скринах то как у меня выглядит статичный вариант с двумя потоками.
Кликните здесь для просмотра всего текста
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
        public class Form1 : Form
        {
            int tCount = 0;
            public static List<byte[]> datalist = new List<byte[]>();
            public static List<Color> endcolorlist = new List<Color>();
            public static List<Thread> threadlist = new List<Thread>();
            ITimer timer;
            public Form1(int ThreadCount)
            {
                DoubleBuffered = true;
                Paint += HandlePaint;
                Click += FormClick;
                FormBorderStyle = FormBorderStyle.FixedSingle;
                ClientSize = new System.Drawing.Size(128 * 8 + 30 + 30, 512 + 30 + 30 + 30);
                MaximizeBox = false;
 
                tCount = ThreadCount;
                for (var i = 0; i < tCount; i++)
                    datalist.Add(File.ReadAllBytes(listfiles[0]));
                for (var i = 0; i < tCount; i++)
                    endcolorlist[i] = Color.Black;
                timer = new WinMmTimer.Timer();
                CreateTimer(timer, 1);
            }
            public void CreateTimer(ITimer t, int ms)
            {
                t.Start(ms, DoInvalidate);
            }
            public void DoInvalidate()
            {
                Invalidate();
            }
            public void UpdateData1(byte[] d, Color c, long sw)
            {
                endcolor1 = c;
                data1 = d;
                System.Threading.Thread.Sleep(3);
            }
            public void UpdateData2(byte[] d, Color c, long sw)
            {
                endcolor2 = c;
                data2 = d;
                System.Threading.Thread.Sleep(3);
            }
            public void Sort1()
            {
                CombSort(1.247331, data1, this);
            }
            public void Sort2()
            {
                CombSort(1.247330950103979, data2, this);
            }
            void FormClick(object sender, EventArgs e)
            {
                if (tCount > 0)
                {
                    threadlist.Add(new Thread(Sort1));
                    threadlist.Add(new Thread(Sort2));
                    for (var i = 0; i < tCount; i++)
                        threadlist[i].Start();
                }
                else
                {
                    for (var i = 0; i < tCount; i++)
                        threadlist[i].Abort();
                    timer.Stop();
                }
            }
            void HandlePaint(object sender, PaintEventArgs e)
            {
                Graphics g = e.Graphics;
                Pen p = new Pen(Color.Yellow);
                g.DrawRectangle(p, 20, 20, 128 * 8 + 20, 256 + 10 + 10);
                g.DrawRectangle(p, 20, 256 + 30 + 20, 128 * 8 + 20, 256 + 10 + 10 );
                int barstep = (int)(512 / tCount);
                if (data1.Length <= 1024)
                {
                    for (int x = 0; x < datalist[0].Length; x++)
                    {
                        int colorcode = 223 * data1[x] / 256 + 32;
                        List<Brush> brushlist = new List<Brush>();
                        for (var i = 0; i<tCount; i++)
                        {
                            brushlist.Add(endcolorlist[i] != Color.Black ? new SolidBrush(endcolorlist[i]) : new SolidBrush(Color.FromArgb(0xFF, colorcode, colorcode, colorcode)));
                            g.FillRectangle(brushlist[i], x + 30, ClientSize.Height - datalist[i].Length - barstep - 30*x - 30, 1, datalist[i].Length);
                        }
                    }
                }
                else
                    Text = "Файл слишком большой";
            }
        };
 
        public static List<string> listfiles = new List<string>();
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine("MegaSort (c) 2023\n");
            if (args.Length > 0)
                if ((listfiles = FillFilesList(args)).Count == 0)
                {
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.WriteLine("No file to sort.");
                }
                else
                {
                    Form1 form = new Form1(2);
                    form.ShowDialog();
                }
            else
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Usage:  megasort [filename1] - filenames separated by space\n");
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.WriteLine("Sample: megasort readme.txt");
            }
            sw.Stop();
        }
        public static List<string> FillFilesList(IEnumerable<string> args)
        {
            List<string> list = new List<string>();
            foreach (var ar in args) list.Add(ar);
            return list;
        }
        public static void CombSort(double dx, byte[] Gbytes, Form1 f)
        {
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            ulong paints = 0;
            ulong gap = (ulong)Gbytes.Length;
            bool swapped = false;
            while ((gap > 1) || swapped)
            {
                ulong oldgap = gap;
                gap = (ulong)(gap / dx);
                if (oldgap != gap)
                {
                    if (gap < 1) gap = 1;
                    ulong i = 0;
                    ulong m = gap;
                    swapped = false;
                    while (m < (ulong)Gbytes.Length)
                    {
                        if (Gbytes[i] > Gbytes[m])
                        {
                            swapped = true;
                            byte t = Gbytes[i];
                            Gbytes[i] = Gbytes[m];
                            Gbytes[m] = t;
                            sw.Stop();
                            f.UpdateData2(Gbytes, Color.Black, sw.ElapsedMilliseconds);
                            paints++;
                            sw.Start();
                        }
                        i++;
                        m = i + gap;
                    }
                }
            }
            sw.Stop();
            f.UpdateData2(Gbytes, Color.Green, sw.ElapsedMilliseconds);
            paints++;
            sw.Start();
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("CombSort {0} ms", sw.ElapsedMilliseconds);
            sw.Stop();
        }
Миниатюры
Затык с ООП и динамическими функциями   Затык с ООП и динамическими функциями  
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.05.2023, 10:07
Ответы с готовыми решениями:

Работа с динамическими массивами и функциями
Вот что я пытался делать. Я &quot;взял&quot; первое и последнее число Memo. Потом что-то не получается. Послезавтра экзамен, завтра надо закрыть все...

Работа с динамическими массивами и функциями С++
Всем привет, столкнулся с проблемой которую не могу решить, нужно добавить столбец в конец матрицы, буду очень рад помощи. #include...

В чем различие между функциями VBA и функциями Excel?
В чем различие между функциями VBA и функциями Excel. Скажите пожалуйста , в гугле не могу найти)

19
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,748
Записей в блоге: 1
23.05.2023, 10:53
Цитата Сообщение от belalugoci Посмотреть сообщение
автоматически объекты создавать в нужном количестве просто передавая нужно число в конструктор
Это задача не конструктора, конструктор обычно используется для инициализации экземпляра. Если вам надо обработать несколько блоков (хотя не понятно каких блоков ведь в коде есть массив данных, поэтому примем за блок экземпляр), то напишите фабрику. Эта фабрика будет вам "печь пироги" в нужном количестве.
Цитата Сообщение от belalugoci Посмотреть сообщение
отдавать перечень функций, которые будут участвовать в изменении данных каждого блока.
Для этого придуманы интерфейсы - тыц, тыц.
1
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.05.2023, 11:42  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
Это задача не конструктора, конструктор обычно используется для инициализации экземпляра
пусть так, я под конструктором понимаю не определение в ООП, а свойство - создание чего-либо.

Цитата Сообщение от Uswer Посмотреть сообщение
Если вам надо обработать несколько блоков (хотя не понятно каких блоков
Блок - это картинка X*Y которая заполняется из массива его элементами в виде столбцов определенного цвета (на скинах оттенки серого). Блоков может быть 1 и 10 и 100, при этом в datalist я могу сами данные разместить пронумерованные по списку, а вот функции которые рисуют сейчас только две и они статичные. Как я понимаю я где-то в коде говорю - создать, мне возвращается номер блока и в последующих обращениях на перерисовку я указываю параметром этот номер. А вот ответная часть как-то по этому номеру должна уметь определять какой функцией сортировки его обрабатывать.

Цитата Сообщение от Uswer Посмотреть сообщение
поэтому примем за блок экземпляр
см.выше

Цитата Сообщение от Uswer Посмотреть сообщение
то напишите фабрику. Эта фабрика будет вам "печь пироги" в нужном количестве
это слишком абстрактно.

Цитата Сообщение от Uswer Посмотреть сообщение
Для этого придуманы интерфейсы - тыц, тыц.
пока не увидел взаимосвязи, почитаю плотнее.

Добавлено через 17 минут
Цитата Сообщение от Uswer Посмотреть сообщение
фабрика
вроде тут написано нормально, если не трудно посмотрите стоит ли опираться на эту статью.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
23.05.2023, 12:27
Цитата Сообщение от belalugoci Посмотреть сообщение
это слишком абстрактно.
У вас вопрос настолько абстрактный, что по другому и не ответишь. И прикрепленная простыня может конечно и даст понимания, но тратить кучу времени на расшифровку код не очень хочется.

Как создать N-объектов? Вам ответили -- фабрика. Ну либо цикл for(n), вообще не понимаю как вы дошли до ООП, но застряли на этом.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyType
{  }
 
class FactoryMyType
{
    public MyType[] Create(int n)
    { 
        var arr = new MyType[n];
        for (var i = 0; i < n; i++)
        {
            arr[i] = new MyType();
        }
 
        return arr;
    }
}
Цитата Сообщение от belalugoci Посмотреть сообщение
при этом в идеале конструктору кроме числа блоков хорошо бы отдавать перечень функций, которые будут участвовать в изменении данных каждого блока.
делегаты? Если один обработчик для каждого создаваемого элемента -- закинули делегат в фабрику, а потом фабрика штампует вам готовые элементы с передачей этого делегата(ов) каждому.

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
class MyType
{
 
    public MyType(Action action)
    { }
}
 
class FactoryMyType
{
    Action action;
 
    public FactoryMyType(Action action)
    {
        this.action = action;
    }
 
    public MyType[] Create(int n)
    {
        var arr = new MyType[n];
        for (var i = 0; i < n; i++)
        {
            arr[i] = new MyType(action);
        }
 
        return arr;
    }
}
Ну либо вообще объект, который содержать нужный метод. Такой подход позволяет управлять этим "методом для всех", и в случае чего заменить его на другой.

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
class ActionAccessor
{
    public Action Action { get; set; }
}
 
class MyType
{
    ActionAccessor actionAccessor;
 
    public MyType(ActionAccessor actionManager)
    {
        this.actionAccessor = actionManager;
    }
}
 
class FactoryMyType
{
    ActionAccessor actionAccessor;
 
    public FactoryMyType(ActionAccessor actionAccessor)
    {
        this.actionAccessor = actionAccessor;
    }
 
    public MyType[] Create(int n)
    {
        var arr = new MyType[n];
        for (var i = 0; i < n; i++)
        {
            arr[i] = new MyType(actionAccessor);
        }
 
        return arr;
    }
}
Добавлено через 4 минуты
Цитата Сообщение от belalugoci Посмотреть сообщение
вроде тут написано нормально, если не трудно посмотрите стоит ли опираться на эту статью.
глянул бегло... я бы с большей вероятностью использовал интерфейс, если на то пошло. Абстрактный класс используется в том случае когда создаваемые объекты 100% являются общими сущностями и нужно где-то упаковать внутренний код, чтобы не шибко дублировать.
1
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,748
Записей в блоге: 1
23.05.2023, 12:29
belalugoci, в вашем коде творится что-то несуразное - потоки, таймер, измеритель времени, сами данные и методы их обработки всё это в куче. Разделите по классам - массивы данных и методы их сортировки в один класс, UI в классе формы.
Измеритель времени применён не правильно, т.к. в работу метода сортировки вклинен UI.
2
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
23.05.2023, 13:14  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
в вашем коде творится что-то несуразное - потоки, таймер, измеритель времени, сами данные и методы их обработки всё это в куче
я не умею в ООП совсем, только процедурно и только последовательно.

Цитата Сообщение от Uswer Посмотреть сообщение
Разделите по классам - массивы данных и методы их сортировки в один класс, UI в классе формы.
не понимаю как это делается в принципе, не могу в голове уложить всё это совсем, за более чем 25 лет делал много подходов к ООП но не понимаю его совсем, только ASM, PAS, C. Даже когда пользовался Делфи то писал всё внутри формы.

Цитата Сообщение от Uswer Посмотреть сообщение
Измеритель времени применён не правильно, т.к. в работу метода сортировки вклинен UI
ну я делаю паузу и запускаю вновь после UI, как еще можно? Я уже как-то тут спрашивал, ответа не дали.

Цитата Сообщение от Wolfdp Посмотреть сообщение
Как создать N-объектов? Вам ответили -- фабрика. Ну либо цикл for(n), вообще не понимаю как вы дошли до ООП, но застряли на этом
я понимаю что цикл, но не понимаю что внутри цикла. Я до ООП не дошел, скорее сижу на входе и не знаю как дверь открыть.

Цитата Сообщение от Wolfdp Посмотреть сообщение
делегаты?
То есть не функции будут в списке, а классы? А данные в классе в конструкторе создавать?

Цитата Сообщение от Wolfdp Посмотреть сообщение
глянул бегло... я бы с большей вероятностью использовал интерфейс, если на то пошло. Абстрактный класс используется в том случае когда создаваемые объекты 100% являются общими сущностями и нужно где-то упаковать внутренний код, чтобы не шибко дублировать
я совсем не понял написанное.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
23.05.2023, 14:24
Цитата Сообщение от belalugoci Посмотреть сообщение
То есть не функции будут в списке, а классы? А данные в классе в конструкторе создавать?
Без конкретики, что должна делать ваша программа, могу только сказать что в зависимости от ТЗ, можно передавать что душе угодно: делегаты, объект, за проезд...
0
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,748
Записей в блоге: 1
23.05.2023, 19:14
Для начала отделите данные от UI
Класс данных
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
using System.Diagnostics;
public SortedData
{
    public byte[] DataArray { get; set; } //массив для сортировки
    
    private long _iteration; //номер текущей перестановки при сортировке
    public long Iteration 
    {
        get{return _iteration;}
    }
    
    private long _sortingTime; //время затраченное на сортировку
    public long SortingTime 
    {
        get {return _sortingTime;}
    }
    
    public SortedData(byte[] data)
    {
        DataArray = data;
    }
    
    public void CombSort(object?  dx)
    {
            dx = (double)dx;
            ulong paints = 0;
            ulong gap = (ulong)_DataArray.Length;
            bool swapped = false;
            Stopwatch sw = Stopwatch.StartNew();
            while ((gap > 1) || swapped)
            {
                ulong oldgap = gap;
                gap = (ulong)(gap / dx);
                if (oldgap != gap)
                {
                    if (gap < 1) gap = 1;
                    ulong i = 0;
                    ulong m = gap;
                    swapped = false;
                    while (m < (ulong)_DataArray.Length)
                    {
                        if (_DataArray[i] > _DataArray[m])
                        {
                            swapped = true;
                            byte t = _DataArray[i];
                            _DataArray[i] = _DataArray[m];
                            _DataArray[m] = t;
                            _iteration++;
                        }
                        i++;
                        m = i + gap;
                    }
                }
            }
            sw.Stop();
            _sortingTime = sw.ElapsedMilliseconds;
        }
}

Затем где-то в форме можно применить так
C#
1
2
3
4
5
6
7
8
double[] dxs = new double[] {1.247331, 1.247330950103979};
SortedData sd;
for (int i = 0; i < dxs.Length; i++)
{
  sd = new SortedData(listfiles[0]);
  threadlist.Add(new Thread(sd.CombSort));
  threadlist[i].Start(dxs[i]);
}
Для обновления данных на графике можно либо в классе SortedData создавать событие, а в форме подписаться на него, либо наоборот получать объект синхронизации (семафор например) от других потоков (формы) и дожидаться отрисовки текущей итерации сортировки. НО при всём этом замер времени сортировки будет не верным, т.к. в процесс сортировки вклиниваются другие операции.
1
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
24.05.2023, 05:16  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
Без конкретики, что должна делать ваша программа
я вроде написал что она делает, может конечно не то что ожидается. попробую еще раз.
при запуске программа ждет событие (клик на форму например), после чего в форме на канвасе показывается графически преобразование массива на разных этапах сортировки. после окончания программы (последнего потока) - конец.
сама программа при старте формирует Х баров (прямоугольников), в которых изображены в виде столбцов значения в массиве (гистограмма). Сейчас я в программе для того чтобы выводить бары должен явно заходить в код каждой функции и руками прописывать что и где рисуется. Когда это делаешь 1 раз, то можно и так, а когда 18-40 раз за пол часа, то это утомляет. Идея в том чтобы я мог любому алгоритму сортировку (хоть старому коду, хоть вновь написанному) весьма легко передавать информацию о его месте отрисовки. В моём понимании в Main я создаю что-то (запускаю конcтрукторы), которые определяют ID, обращаясь к определенному коду и указывая ID я могу однозначно понимать где рисовать и что рисовать.
Не обязателен такой алгоритм, просто я его так вижу, но с ООП я не представляю как именно нужно строить задачу в конечном итоге.

Цитата Сообщение от Uswer Посмотреть сообщение
Для начала отделите данные от UI
я наверное понимаю что вы делаете, но не понимаю зачем именно так и в чем отличие от моего варианта. Для меня это выглядит как яйцо только с другого ракурса.

Цитата Сообщение от Uswer Посмотреть сообщение
Затем где-то в форме можно применить так
а, то есть смысл в том чтобы сортировки реализовать как методы и их уже засовывать в потоки, но как определять какой метод используется и где ему место на форме для отрисовки?

Цитата Сообщение от Uswer Посмотреть сообщение
Для обновления данных на графике можно либо в классе SortedData создавать событие, а в форме подписаться на него
XD вы меня добиваете

Цитата Сообщение от Uswer Посмотреть сообщение
либо наоборот получать объект синхронизации (семафор например) от других потоков (формы) и дожидаться отрисовки текущей итерации сортировки
я два потока чтобы сделать до седых волос читал, семафоры не в этой жизни ((((

Цитата Сообщение от Uswer Посмотреть сообщение
НО при всём этом замер времени сортировки будет не верным, т.к. в процесс сортировки вклиниваются другие операции.
а почему вариант с
C#
1
2
3
sw.Stop();
f.UpdateData2(Gbytes, Color.Black, sw.ElapsedMilliseconds);
sw.Start();
не работает? таймер останавливается и вновь запускается после отрисовки. то что sw передается в отрисовку не смотрите, я просто ранее выводил на форме время, сейчас это не нужно.
я буду благодарен если покажете как именно нужно замерять скорость выполнения кода, я создавал такую тему но никто не ответил. Обычно я запускаю 10-20 прогонов и использую среднее значение. Обычно этого достаточно чтобы видеть разницу между O(n), O(nLOG2(n)) и O(n^2).
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
24.05.2023, 10:39
Цитата Сообщение от belalugoci Посмотреть сообщение
Сейчас я в программе для того чтобы выводить бары должен явно заходить в код каждой функции и руками прописывать что и где рисуется.
Выглядит как кастомный контрол, который на вход получает массив, и отрисовывает для этого массива ваши "столбики".

Что по отрисовке я бы сделал:
- задал фиксированый Bitmap с unsafe code, чтобы работать с пикселями напрямую
- ширина Bitmap -- 4px * n, где n -- количество элементов в arr
- высота -- Min(максимальный элемент, максимально адекватное разрешение монитора)
- получаем массив, и тупо рисуем линии на Bitmap (с поправкой на высоту)
- далее -- тупо делаем Draw текущего Bitmap на форму.

p.s. код таки лучше не сваливать в кучу, а расфасовать по классам, раз взялись за ООП.
1
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,748
Записей в блоге: 1
24.05.2023, 11:03
Цитата Сообщение от belalugoci Посмотреть сообщение
я наверное понимаю что вы делаете, но не понимаю зачем именно так и в чем отличие от моего варианта.
Массив данных и метод его сортировки размещены в своём классе. Вы можете создать сколько угодно экземпляров этого класса, при этом все они могут работать с разными массивами, а один и тот же метод сортировки может выполнятся разными потоками, но сортироваться будет именно экземплярный массив.
Цитата Сообщение от belalugoci Посмотреть сообщение
но как определять какой метод используется и где ему место на форме для отрисовки?
У вас есть список потоков вот по нему и ориентируйтесь. Вообще на форме можно применить FlowLayoutPanel и помещать в неё графики каждого потока. Для рисования графиков в форме должен быть отдельный метод. В нёго из потока надо передавать обрабатываемый (отображаемый) массив.
Цитата Сообщение от belalugoci Посмотреть сообщение
вы меня добиваете
Цитата Сообщение от belalugoci Посмотреть сообщение
я два потока чтобы сделать до седых волос читал
Ну программирование штука такая. А по поводу отрисовки и замера времени сортировки скажу так: либо одно, либо другое. Либо вы измеряете чистое время метода сортировки, либо вы получите время затраченное на оба действия вместе (сортировка+отрисовка). Можно придумать нечто среднее - типа на каждом шаге перестановки сохранять в отдельный список индексы элементов исходного массива, а на форме с определённой периодичностью строить график опираясь на эти индексы. Тогда замер времени сортировки будет близок к реальному, но с оговоркой на создание дополнительных данных.
Цитата Сообщение от belalugoci Посмотреть сообщение
а почему вариант с .. не работает?
Рабочий вариант, НО есть принцип SRP, который Вы нарушаете добавляя в код сортировки работу с формой. Когда вы пишите весь код монолитом в классе формы это вполне объяснимо и даже нормально, но если отделять мух от котлет, то получается нарушение.
1
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
24.05.2023, 11:38  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
Массив данных и метод его сортировки размещены в своём классе. Вы можете создать сколько угодно экземпляров этого класса, при этом все они могут работать с разными массивами, а один и тот же метод сортировки может выполнятся разными потоками, но сортироваться будет именно экземплярный массив.
ок, кажется понимаю, а рисовать будет другой класс, которому отдаём ссылку на массив из первого класса и ссылку на форму - куда отрисовать, так?

Цитата Сообщение от Uswer Посмотреть сообщение
В нёго из потока надо передавать обрабатываемый (отображаемый) массив.
то есть мы привязываемся сортировкой к отрисовке? я думал чтобы рисование не было связано, поэтому по тику таймера рисование сделал.

Цитата Сообщение от Uswer Посмотреть сообщение
Ну программирование штука такая
ну я без проблем программирую видеокарту Atari 80-x годов, VGA на Си, в общем где-то поближе к железу, тут скорее проблема в том как сложное уместить в простое. Когда читаешь что-то ООПэшное, то создается ощущение что делать попроще никто и не собирался ), кода всегда очень много, но он просто ничего не делает, читать такое мне практически невозможно.

Цитата Сообщение от Uswer Посмотреть сообщение
А по поводу отрисовки и замера времени сортировки скажу так: либо одно, либо другое
Почему? Когда происходит рисование замеры не производятся, значит в переменной sw только результат работы кода сортировки.

Цитата Сообщение от Uswer Посмотреть сообщение
НО есть принцип SRP, который Вы нарушаете добавляя в код сортировки работу с формой
всегда есть основной процесс и зависимые от него, мне кажется принцип SPR в данном случае не об этом. Иначе что изменилось бы если бы я код рисования вставил не в сортировку а в Main?

Цитата Сообщение от Uswer Посмотреть сообщение
но если отделять мух от котлет, то получается нарушение
Например класс Bitmap и в нем куча методов (в вики пример про форму и её печать) по работе с BMP файлами. Всё в одном классе. Или с того же NuGet можно качать классы по обработке изображений, тоже класс один, а методов очень много и все в одном классе. Можно конечно создавать и перехватывать события (никогда не пользовался) и наверное тогда связи никакой не будет, но тогда это уже не класс Bitmap, а скорее 39 классов с одним методом на класс. Пока не понимаю для чего это.
Мне ООП не понравился в основном тем (и за 25 лет ни кто не смог опровергнуть это, нам в целом в ВУЗе это и говорили, да и читал тоже много об этом), что он перегружает код лишним текстом не давая явного преимущества на массе вариантов кода. Как и в моей теме потребность в ООП появилась на стыке определенных задач. Я давно, в начале 90-х делал что-то похожее на Си, без ООП, просто было давно и уже такое не делал лет 20, да и решение для DOS в данном случае мне не нужно. Я даже не знаю как это делать в Watcom C.
С год назад смотрел на гитхабе код TimSort сделанный по тру правилам ООП, при этом сам код сортировки занимал 5-7% кода, остальное было описанием классов и методов, часто однострочных. Читать практически невозможно.

Добавлено через 4 минуты
Цитата Сообщение от Wolfdp Посмотреть сообщение
чтобы работать с пикселями напрямую
зачем?

Цитата Сообщение от Wolfdp Посмотреть сообщение
код таки лучше не сваливать в кучу, а расфасовать по классам, раз взялись за ООП
это понятно, вопрос в самой реализации, в целом наверное у меня сейчас есть что дописать в коде, если уткнусь во что-то то можно будет задать вопрос по существу.

Цитата Сообщение от Wolfdp Посмотреть сообщение
Выглядит как кастомный контрол, который на вход получает массив, и отрисовывает для этого массива ваши "столбики"
кстати это идея, можно рисовать на элементе который предоставляет список контролов, если их больше и не входит на форму то будет скролл. Хм.
0
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,748
Записей в блоге: 1
24.05.2023, 12:30
Цитата Сообщение от belalugoci Посмотреть сообщение
отдаём ссылку на массив из первого класса и ссылку на форму - куда отрисовать, так?
Посредник тут не нужен, рисовать должен метод формы.
Цитата Сообщение от belalugoci Посмотреть сообщение
то есть мы привязываемся сортировкой к отрисовке?
Именно.
Цитата Сообщение от belalugoci Посмотреть сообщение
Когда читаешь что-то ООПэшное, то создается ощущение что делать попроще никто и не собирался
На самом деле (в старой книжке вычитал) до сих пор существует два вида программирования: процедурное и объектно-ориентированное. Первое это примерно то, как пишите вы, т.е. весь код делится лишь на отдельные методы, которые делают логически законченную работу. При этом данные размещаются в основном теле программы и доступны практически везде. Второй подход предполагает создание объектов (классов), которые инкапсулируют данные и методы их обработки. ООП позволяет относительно легко сосредотачиваться на конкретной проблеме или задаче не затрагивая весь остальной код. В процедурном подходе поиск и исправление проблем непосильная задача если приложение объёмное. ООП позволяет вести командную разработку.
Цитата Сообщение от belalugoci Посмотреть сообщение
всегда есть основной процесс и зависимые от него, мне кажется принцип SPR в данном случае не об этом.
Об этом. Метод называется CombSort, поэтому он должен только сортировать. Да, есть такая штука как DI, но тогда надо применять её правильно.
Цитата Сообщение от belalugoci Посмотреть сообщение
если уткнусь во что-то то можно будет задать вопрос по существу.
Однозначно уткнётесь, т.к. в вашем коде присутствует ошибка, а именно при работе с datalist в методе HandlePaint этот самый datalist меняется другими потоками. Как следствие отображаемые данные минимум не соответствуют действительности.
Цитата Сообщение от belalugoci Посмотреть сообщение
Почему? Когда происходит рисование замеры не производятся
Это пол беды. Можно было бы применить в CombSort асинхронный вызов метода отрисовки, это сейчас вообще маст-хэв, но боюсь, что тогда вы вообще бросите начатое.
1
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
24.05.2023, 15:04  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
Именно
а для чего? я наоборот хотел рисование исключить из процесса.

Цитата Сообщение от Uswer Посмотреть сообщение
На самом деле (в старой книжке вычитал)
я об этом же. я один, после меня буду читать только я сам, зачем сложности.

Цитата Сообщение от Uswer Посмотреть сообщение
Метод называется CombSort, поэтому он должен только сортировать
я уже подзапустался в каком случае вы говорите о классе а в каком о методе.

Цитата Сообщение от Uswer Посмотреть сообщение
Однозначно уткнётесь, т.к. в вашем коде присутствует ошибка, а именно при работе с datalist в методе HandlePaint этот самый datalist меняется другими потоками. Как следствие отображаемые данные минимум не соответствуют действительности.
Хм, каждая сортировка работает со своими данными, изменяя datalist[0] вы никак не влияете на datalist[1].

Цитата Сообщение от Uswer Посмотреть сообщение
Это пол беды. Можно было бы применить в CombSort асинхронный вызов метода отрисовк
всё же не понимаю зачем такие сложности. Таймер паузится и продолжается только после прорисовки.
0
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,748
Записей в блоге: 1
24.05.2023, 15:47
Цитата Сообщение от belalugoci Посмотреть сообщение
я наоборот хотел рисование исключить из процесса.
Из подсчёта времени вы его исключили. Хорошо пусть будет так.
Цитата Сообщение от belalugoci Посмотреть сообщение
зачем сложности
Не сложности, а структурирование кода если хотите.
Цитата Сообщение от belalugoci Посмотреть сообщение
я уже подзапустался в каком случае вы говорите о классе а в каком о методе
Класс содержит члены и метод один из них, поэтому они неразрывно связаны. Если какой-то принцип должен соблюдаться, то везде в пределах отдельного класса.
Цитата Сообщение от belalugoci Посмотреть сообщение
всё же не понимаю зачем такие сложности
Поэтому я только упомянул об этом, мол "такая возможность есть, а вот применять её пока рано".
Цитата Сообщение от belalugoci Посмотреть сообщение
изменяя datalist[0] вы никак не влияете на datalist[1]
Имелась ввиду возможность возникновения такой ситуации:
UI начинает перерисовывать графики. Взяв первый элемент первого массива (datalist[0]) он его рисует. Затем управление получает Поток1, который меняет первый элемент с, допустим, вторым. Управление возвращается потоку UI и он переходит к рисованию второго элемента первого массива, но там находится та же величина, что уже была нарисована ранее, а первый нарисованный сегмент не соответствует действительности. Далее звучит звук видео.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
24.05.2023, 16:26  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
UI начинает перерисовывать графики. Взяв первый элемент первого массива (datalist[0]) он его рисует. Затем управление получает Поток1, который меняет первый элемент с, допустим, вторым. Управление возвращается потоку UI и он переходит к рисованию второго элемента первого массива, но там находится та же величина, что уже была нарисована ранее, а первый нарисованный сегмент не соответствует действительности
Поток0 работает с datalist[0], Поток1 с datalist[1], один к другому не лезет нигде в коде.

Ладно, неблагодарное это дело - ковыряние в устоявшихся традициях. Лучше посмотрим что я наговнокодю.
0
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,748
Записей в блоге: 1
24.05.2023, 16:36
belalugoci, да причём тут Поток0 и Поток1. Пример приведён для двух потоков: UI и Поток0. Один рисует другой сортирует. Работа с потоками всегда требует щепетильности. Как только появляются потоки тут же появляются и объекты синхронизации их работы, если только не требуется действительно параллельная обработка чего либо.
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
24.05.2023, 16:38  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
да причём тут Поток0 и Поток1. Пример приведён для двух потоков: UI и Поток0. Один рисует другой сортирует
а зачем одновременно рисовать и сортировать? это у меня не используется совсем. Пока рисует сортировка не работает.
0
2287 / 1603 / 400
Регистрация: 26.06.2017
Сообщений: 4,748
Записей в блоге: 1
24.05.2023, 17:55
Цитата Сообщение от belalugoci Посмотреть сообщение
Пока рисует сортировка не работает.
Так ли?
Цитата Сообщение от belalugoci Посмотреть сообщение
а зачем одновременно рисовать и сортировать?
А зачем тогда потоки?
0
 Аватар для belalugoci
475 / 294 / 29
Регистрация: 01.06.2018
Сообщений: 3,676
24.05.2023, 18:15  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
Так ли?
Так

Цитата Сообщение от Uswer Посмотреть сообщение
А зачем тогда потоки?
Мне кажется для очевидного, чтобы не ждать последовательно кучу сортировок и выполнить все параллельно.
За вечер я могу запускать тесты раз 200, при последовательном выполнении это занимает кратно большее время.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.05.2023, 18:15
Помогаю со студенческими работами здесь

FILE_MAP_EXECUTE затык
Вроди и задача не сложная, но завис как начинающий=-O Скажем есть байты экзешника, как посредством FileMapping заставить систему сжевать...

Затык с VARIANT
Такой вопрос. В переменную типа &lt;VARIANT&gt;, точнее в поле vt возвращается значение VT_DISPATCH, так вот, чем будет проинициализировано поле...

затык с модулями
всем снова драске. в текущем каталоге лежит main.py с таким содержанием: import sys sys.path.append('.') import...

Затык с SQL-запросом
Доброго дня, форумчане. Что-то не могу никак победить SQL-запрос. В общем есть таблица движения по сотрудникам и в ней два поля IDBest и...

Затык с конструктором thread
Здравствуйте. Есть проблема - имеется код функции void CalculatingChecker () { { unique_lock&lt;mutex&gt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru