Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 07.07.2014
Сообщений: 14
1

Показать результаты итераций на отдельной форме

10.10.2015, 02:59. Показов 1820. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Приветствую!

Допустим, есть процедура, в которой есть цикл, выполняющийся достаточно долгое время. Хочется сделать так, чтобы перед началом цикла открылась некоторая вторая форма, в которой есть, например, ListBox. По завершении каждой итерации цикла предполагается добавление новой строки в ListBox. При этом, основная форма "блокируется" (так как в ней выполняется сам цикл - их не предполагается выполнять в отдельных потоках), однако вторая форма должна быть активной и доступной для использования.

Пример:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void RunAll()
{
    // открыть отдельную форму с листбоксом
    for (int i = 0; i < 10; i++)
    {
         try
         {
             Run(i);
               // добавить в листбокс строку "Успешно"
         }
        catch (Exception ex)
        {
               // добавить в листбокс строку "Ошибка: " + ex.Message
        }        
    }
    ...
}
 
void Run(int i)
{
    // что-то делаем
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.10.2015, 02:59
Ответы с готовыми решениями:

Как сверить результаты итераций цикла?
Из базы данных выгружаю информацию циклом foreach и при этом мне нужно сравнить результат итерации...

ProgressBar в отдельной форме
Подскажите разобраться, пожалуйста! Есть список элементов обработка которых занимает некоторое...

БД. Добавление в отдельной форме
Добрый день. Вопрос такой, создаю БД привязанную к Access'у. Подключил добавление на главной форме,...

Изменение в отдельной форме
Добрый день! Может кто нибудь помочь ?Если делать изменение с выводом строчки в тексбоксы,то всё...

8
3675 / 2587 / 718
Регистрация: 02.08.2011
Сообщений: 6,955
10.10.2015, 03:19 2
1.Определите событие в главной форме, которое будете файрить в конце каждой итерации цикла.
2.Создайте вторую форму, определите метод-подписчик на событие в этой форме и откройте ее в диалоговом режиме.
3.Запустите цикл. Profit
0
0 / 0 / 0
Регистрация: 07.07.2014
Сообщений: 14
10.10.2015, 03:36  [ТС] 3
Не уверен, что до конца понял, но.. если я все правильно понимаю, ключевая проблема в том, что вторую форму я должен запускать отдельным потоком и напрямую заставить ее реагировать на события в первой форме не получится (во всяком случае, у меня это не получилось, в том числе и со всякими BackgroundWorker).

Добавлено через 10 минут
На всякий случай, еще. Помимо всего прочего, я пытался сделать так: во второй форме сделал static ObservableCollection, содержащий список сообщений. Идея была в том, чтобы из первой формы добавлять в эту коллекцию объекты (что удавалось без проблем, даже при объявленной в другом потоке второй форме - что логично, учитывая static). А уже во второй форме обрабатывал событие CollectionChanged для этой коллекции. И вот даже в этом случае программа падает из-за того, что форма сделана в другом потоке.

Единственный условно рабочий вариант, который удался - во второй форме сделать кнопку, которая при нажатии дозаливает новые элементы в ListBox. Допустим, даже получится настроить обновление по таймеру. Но все равно как-то неспортивно - какую-нибудь подписку сделать интереснее было бы.
0
3675 / 2587 / 718
Регистрация: 02.08.2011
Сообщений: 6,955
10.10.2015, 04:17 4
А не, не тут то было). Сначала выполняется цикл в потоке первой формы, затем, даже если была подписка, пачкой заполняется листбокс. А почему нельзя использовать рабочие потоки? Гарантированно будет работать.
0
0 / 0 / 0
Регистрация: 07.07.2014
Сообщений: 14
10.10.2015, 04:28  [ТС] 5
"...А почему нельзя использовать рабочие потоки? Гарантированно будет работать."

BackgroundWorker? Если да, то у меня по крайней мере не взлетело (но я вполне допускаю, что криво использовал). На всякий случай еще нюанс - процессы Run() я не хочу запускать отдельными потоками, а именно вторую форму.
0
3675 / 2587 / 718
Регистрация: 02.08.2011
Сообщений: 6,955
10.10.2015, 04:48 6
Цитата Сообщение от balalexv Посмотреть сообщение
процессы Run() я не хочу запускать отдельными потоками,
В том то и дело, что рабочие потоки на то и рабочие, используются для вычислительных операций.
Вот что-то похожее на правду, но все равно кривое решение - так не делают.
Application.DoEvents рулит).

Код первой формы:
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
namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private Form2 form2 = new Form2();
 
        public Form1()
        {
            InitializeComponent();
            IterationCompleted += form2.Handler;
        }
 
        public event EventHandler<IterationCompletedEventArgs> IterationCompleted;
 
 
        private void RunAll()
        {
            // открыть отдельную форму с листбоксом
            form2.Show();
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    Run(i);
                    IterationCompleted(this,new IterationCompletedEventArgs(i,true));
                }
                catch (Exception ex)
                {
                    // добавить в листбокс строку "Ошибка: " + ex.Message
                }
            }
        }
 
        private void Run(int i)
        {
              Thread.Sleep(1000);
              Debug.Write(i);
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            RunAll();
        }
    }
 
 
    public class IterationCompletedEventArgs : EventArgs
    {
        public IterationCompletedEventArgs(int counter, bool isSuccessful)
        {
            IterationNumber = counter;
            IsSuccessful = isSuccessful;
        }
 
        public int IterationNumber { get; private set; }
        public bool IsSuccessful { get; private set; }
    }
}
Вторая форма:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
 
        public void Handler(Object sender, IterationCompletedEventArgs e)
        {
            listBox1.Items.Add(String.Format("Iteration {0}:{1}", e.IterationNumber, e.IsSuccessful));
            Application.DoEvents();
        }
    }
Видимо, потоковая модель для windows forms так работает (или для самой OS, не силен) - диспетчер потоков не передает управление потоку другого окна, пока не будет обработана очередь сообщений для текущего окна.
Поэтому явно заставляем диспетчер обработать сообщения для потока другого окна.

Добавлено через 3 минуты
Но чтобы блокировать первую форму, нужно вторую открывать в диалоговом режиме и уже из второй формы запускать рабочий поток и отображать результат.
0
Эксперт .NET
6508 / 4085 / 1605
Регистрация: 09.05.2015
Сообщений: 9,551
10.10.2015, 04:48 7
Лучший ответ Сообщение было отмечено balalexv как решение

Решение

А так не прокатит (см вложение)?
Вложения
Тип файла: zip TwoForms.zip (13.4 Кб, 15 просмотров)
1
3675 / 2587 / 718
Регистрация: 02.08.2011
Сообщений: 6,955
10.10.2015, 04:59 8
Да, хорошее решение, по сути, вы так и сделали.
0
0 / 0 / 0
Регистрация: 07.07.2014
Сообщений: 14
10.10.2015, 06:16  [ТС] 9
Да, отличное решение. Спасибо всем .
0
10.10.2015, 06:16
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.10.2015, 06:16
Помогаю со студенческими работами здесь

FTP показать результаты ошибок соединение отдельно
Привет! Есть ф-ция: function ftpcheck($host,$login,$pass){ $open =...

Редактирование данных в отдельной форме
Добрый вечер! Подскажите пожалуйста, как вытащить данные из базы и вставить их в TextBox для...

Фильтрация записей в отдельной форме
Не могли бы вы подсказать, как мне на отдельной еще форме сделать фильтрцию, меня интересует, нужно...

Вывести ответ в отдельной форме
Помогите пожалуйста вывести в этой программе отдельно ответ :bravo: сколько не пробовал, все время...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru