7 / 7 / 2
Регистрация: 26.12.2011
Сообщений: 269
1

Использование Tasks для отображения результатов операции

14.01.2016, 16:46. Показов 1195. Ответов 15
Метки нет (Все метки)

Я совсем с этими тасками запутался. Поэтому объясню проще, чтобы мне подсказали. Есть форма, на ней последовательно должны выполняться некоторые операции (в отдельном таске, чтобы форма не фризилась) и отображать результат на форму. Вот схема:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
 
    for(int i = 0; i <arr.Count; i++)
    {
        Process(arr[i]);
        //старт задания
        ...
        //завершение задания, обновление информации на форме
        
    }
    
}
 
public void Process(string str, Form frm1)
{
     Form2 frm2 = new Form2();
     frm2.Owner = frm1;
     //frm2.Show();
     fr2.Process(str);
    
}
Что мне нужно чтобы реализовать задачу? Запустить один таск, который будет запускать другие таск и сам будет обновлять гуи? В общем, я запутался, намекните. Спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.01.2016, 16:46
Ответы с готовыми решениями:

Плагин для отображения результатов опроса в виде диаграмм
Здравствуйте, такая ситуация необходимо на сайте разместить результаты опроса в виде диаграмм, есть...

Применение поразрядной операции с НЕ (~) для обратного отображения битов
Еще раз всем привет! Изучаю Java по Г.Шилдту - Java 6 издание. Собственно пример кода взят прям с...

Использование ListBox для вывода результатов
Есть программа для перевода текста в верхний регистр с выводом результата с помощью функции...

Использование AxWindowsMediaPlayer для отображения позиции трека
Как используя AxWindowsMediaPlayer вывести время проигрывание в label?

15
Эксперт .NET
5474 / 4244 / 1211
Регистрация: 12.10.2013
Сообщений: 12,248
Записей в блоге: 2
14.01.2016, 17:42 2
Цитата Сообщение от young_snake Посмотреть сообщение
Что мне нужно чтобы реализовать задачу?
Вы сами, в принципе, и ответили.
Цитата Сообщение от young_snake Посмотреть сообщение
Запустить один таск, который будет запускать другие таск
А что касается обновления UI, то тут уже варианты, смотря как будет реализовано.
1
975 / 870 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
14.01.2016, 18:19 3
young_snake, формулировка задания расплывчата, но скорее всего-надо сделать 1 метод, который возвращает Task<нужный_тип_результата>,а потом писать что-то в духе:
C#
1
2
3
4
5
6
7
8
9
10
11
  
async void Method(){
 for(int i = 0; i <arr.Count; i++)
    {
        Process(arr[i]);
        var result = await Тот_самый_метод();
        ...
        //обновляем форму из данных в result
        
    }
}
0
7 / 7 / 2
Регистрация: 26.12.2011
Сообщений: 269
14.01.2016, 18:35  [ТС] 4
insite2012, сделал вот так:

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
private async void button1_Click(object sender, EventArgs e)
{
    
    Task t = new Task( () => MyTask(data) );
    t.Start();  
    await Task.WhenAll(t);
    MessageBox.Show("Done");
    
}
 
public void MyTask(List<string> str)
{
    for (int i = 0; i < str.Count; i++)
 
        //Task t = Task.Run( ()=> DoIt(str, this) );
        Task<string> t = Task<string>.Factory.StartNew(() => DoIt(str[i], this));
        string result = t.Result;
        listBox1.Items.Add(result);
    }
    
}
 
 
public string DoIt(string str, Form1 frm1)
{
    
        Form2 frm2 = new Form2();
        frm2.Owner = frm1;
        //frm2.Show();
        frm2.Visible = false;
        //frm2.Show();
        string res = frm2.Process(str);
        while (frm2.IsDisposed == false)
        {
            Thread.Sleep(1000);
        }
 
        return res;
}

Но теперь почему-то пишет:

C#
1
"System.Reflection.TargetInvocationException" в mscorlib.dll
там где Application.Run(new Form1());

C#
1
2
3
4
5
6
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}
Где может быть косяк?

Добавлено через 6 минут
EvilFromHell, ну почему расплывчата? Можно упростить формулировку - нужно выполнять подряд обработку данных, чтобы главная форма не фризилась. А в вашем примере Process(arr[i]) получается будет фризить форму, как у меня было раньше. И я сейчас понял, что если бы все сработало, то месседжбокс "Done", наверное появился бы сразу, а не после выполнения всех операций.
0
975 / 870 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
14.01.2016, 18:50 5
young_snake, в чем смысл этих странных манипуляций? Зачем пытаться открыть какую-то форму не в GUI потоке? зачем какой-то sleep? Зачем вообще метод
Цитата Сообщение от young_snake Посмотреть сообщение
MyTask
когда awaitить можно сразу тот Task, что в цикле? Эксепшен скорее всего уже в этом месте:
Цитата Сообщение от young_snake Посмотреть сообщение
listBox1.Items.Add(result);
Потому что вы обращаетесь к форме не из GUI потока.

Добавлено через 3 минуты
Цитата Сообщение от young_snake Посмотреть сообщение
А в вашем примере Process(arr[i]) получается будет фризить форму, как у меня было раньше.
Я абсолютно не понимаю зачем Process(arr[i]) вообще нужен, поэтому прокомментировать это никак не могу. Я его тупо скопировал у вас. Речь сейчас не о нем.

Добавлено через 7 минут
Вот вам простой пример, создаете приложение винформс, кидаете на форму лейбл, а обработчике события Load пишите:
C#
1
2
3
4
5
6
7
8
        private async void Form1_Load(object sender, EventArgs e)
        {
            for(int i = 0; i < 10; i++)
            {
               label1.Text = await Task<string>.Run(() => { Thread.Sleep(3000); return DateTime.Now.ToLongTimeString(); });
               
            }
        }
Лейбл меняется 10раз раз в 3 секунды без фризов. Делайте аналогично.
1
7 / 7 / 2
Регистрация: 26.12.2011
Сообщений: 269
14.01.2016, 19:41  [ТС] 6
EvilFromHell, спасибо за подробный ответ, буду пробовать.

Добавлено через 18 минут
Process нужен, потому что я создаю новую форму с com-объектом. Но чтобы форма не мешалась, я ее не показываю. А когда объект отработает, я избавлюясь от формы.

Добавлено через 53 секунды
А пользоваться этим объектом в отрыве от формы не получается, дебаггер ругаться начинает.
0
975 / 870 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
14.01.2016, 19:44 7
Цитата Сообщение от young_snake Посмотреть сообщение
Process нужен, потому что я создаю новую форму с com-объектом. Но чтобы форма не мешалась, я ее не показываю. А когда объект отработает, я избавлюясь от формы.
А зачем тут именно форма? Нельзя как-то проще общаться с тем объектом?

Добавлено через 31 секунду
Цитата Сообщение от young_snake Посмотреть сообщение
А пользоваться этим объектом в отрыве от формы не получается, дебаггер ругаться начинает.
Это как-то очень странно, полюбому вы что-то делаете неправильно.
0
7 / 7 / 2
Регистрация: 26.12.2011
Сообщений: 269
14.01.2016, 19:52  [ТС] 8
EvilFromHell, возможно и неправильно, но по-другому не получается. Но вопрос в другом:
что не так с этим местом?

C#
1
2
3
4
Form2 frm2 = new Form2();
frm2.Owner = frm1;
//frm2.Show();
frm2.Visible = false;
Последняя точка останов срабатывает на создании формы (которое идет уже в таске, в новом потоке), а потом выбрасывается исключение "System.Reflection.TargetInvocationException". Не пойму что ему не нравится.
0
Эксперт .NET
6293 / 3914 / 1575
Регистрация: 09.05.2015
Сообщений: 9,217
14.01.2016, 19:56 9
Тип реального исключения указан в свойстве InnerException исключения TargetInvocationException.
0
7 / 7 / 2
Регистрация: 26.12.2011
Сообщений: 269
14.01.2016, 20:07  [ТС] 10
Someone007, да, в самом деле, так все стало более понятно:
{"Создание экземпляра элемента управления ActiveX '54d38bf7-b1ef-4479-9674-1bd6ea465258' невозможно: текущий поток не находится в однопоточном контейнере."} Это особенность компонента такая? (Компонент дает возможность из приложения использовать RDP).
0
975 / 870 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
14.01.2016, 23:56 11
young_snake, у вас этот кусок кода до сих пор внутри Task?
0
7 / 7 / 2
Регистрация: 26.12.2011
Сообщений: 269
15.01.2016, 11:35  [ТС] 12
EvilFromHell, ну да, а куда же я его дену. Я так почитал, то люди пишут что нужно создавать MTA треды с помощью threads, с тасками такое делать, видимо нельзя, или я не нашел способа.
0
975 / 870 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
15.01.2016, 12:21 13
young_snake, еще раз говорю вам, не надо внутри каких-либо потоков, отличных от основного, ничего делать с формами. Все действия с GUI должны быть в одном потоке.

Добавлено через 1 минуту
Скорее всего все дело в этом, если судить по эксепшену. Но что там за компонент и как он работает я не знаю.
0
7 / 7 / 2
Регистрация: 26.12.2011
Сообщений: 269
15.01.2016, 13:03  [ТС] 14
EvilFromHell, да я понимаю, ну тут по-другому никак. Потому что ком-объект привязан ко второй скрытой форме. Поэтому я запускаю вторую форму невидимой, выполняю полезную работу, закрываю форму. Но чтобы в основном интерфейсе в реальном времени отображались результаты действий ком-объекта, нужно запускать этот процесс в отдельном потоке, иначе форма будет фризиться. Но как оказалось это можно делать только если указать параметр STA этому треду при создани. Вот примерно такая же ситуация у человека . Это какая-то особенность com-объектов еще с древних времен, получается. Но в tasks никак не указать какой тип апартаментов использовать. Или я не понял как.
0
975 / 870 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
15.01.2016, 13:17 15
Мне ну абсолютно не ясно, как может быть некий COM объект прибит гвоздями к какой-то форме. Полюбому вы что-то делаете абсолютно неправильно, только вот с ходу не ясно, что же именно. Скиньте проект-скорее всего так станет намного яснее.
0
7 / 7 / 2
Регистрация: 26.12.2011
Сообщений: 269
15.01.2016, 13:31  [ТС] 16
EvilFromHell, отписал в лс. Там закомментировано место, где я пробовал создавать объект без формы, но при этом создавалось исключение.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.01.2016, 13:31
Помогаю со студенческими работами здесь

Использование DISTINCT для отображения уникальных значений
Здравствуйте. Нужна помощь в формировании запроса к базе данных. Есть combobox, который заполняется...

Использование данных из dataGridView для отображения на карте
Есть такая проблема. В Form1 создан gMapControl1private void gMapControl1_Load(object sender,...

Использование ProxyModel для отображения элементов ListView
Здравствуйте, не могу ни как разобраться с таким вот вопросом. У меня есть ListView в нем...

Использование BackgroundWorker в WPF для отображения прогресса загрузки БД
Допустим, есть какой-то UserControl, в который надо вывести таблицу из БД. В том же UserControl`е...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru