Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230

Выполнение длительных операций в отдельном потоке с отображением этапов работы пользователю

31.07.2014, 10:17. Показов 2456. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Например есть код:
C#
1
2
3
4
5
6
7
8
private void button1_Click(object sender, EventArgs e)
{
    listBox1.Items.Add("1");
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://127.0.0.1/123.txt");
    request.Method = WebRequestMethods.Ftp.DeleteFile;
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    listBox1.Items.Add("2");
}
Что я ожидаю: в листбоксе появляется цифра 1, далее идет подключение к фтп, там выполняются необходимые действия, по окончании в листбоксе появляется цифра 2.

Что я получаю: идет подключение к фтп, там выполняются необходимые действия, по окончании в листбоксе появляется цифра 1 и сразу же цифра 2.

Вместо работы с фтп, конечно, могут быть любые другие действия, выполнение которых требует время.

Как в данном случае поступают правильные программисты?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.07.2014, 10:17
Ответы с готовыми решениями:

Выполнение длительных вычислений и операций в отдельном потоке
Добрый вечер. Возникла проблема с вычислениями. Из базы данных (файл) читаются числа и выполняются с ними операции.....

Выполнение операций в отдельном потоке
Например у меня есть функция. void musik() //Создание потоковой функции { Beep(2000,3000); } Как сделать поток,...

Выполнение операций в отдельном потоке
Всем привет! Вот тут я спрашивал, как залогировать батник в RichTextBox: https://www.cyberforum.ru/pascalabc-net/thread1751736.html В...

19
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
31.07.2014, 10:21
pav1uxa, в зависимости от ситуации можно применить Thread.Sleep(...), Thread.Join(), EventWaitHandle, просто ожидание до к-л event-а и так далее...
0
1167 / 885 / 517
Регистрация: 09.04.2014
Сообщений: 2,098
31.07.2014, 13:16
Цитата Сообщение от pav1uxa Посмотреть сообщение
Как в данном случае поступают правильные программисты?
Запускают "действия, выполнение которых требует время" в другом потоке, на пример используя BackgroundWorker
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
05.08.2014, 19:27  [ТС]
Цитата Сообщение от insite2012 Посмотреть сообщение
pav1uxa, в зависимости от ситуации можно применить Thread.Sleep(...)
Как его применить? Если я вставлю туда задержку через Thread.Sleep(), то точно так же сначала подключится к фтп, потом подождет заданное время, потом напишет 1, потом напишет 2...

Почему команды не выполняются в той последовательности, которую я задаю, а выполняются как то одновременно? Как можно сделать чтобы все было последовательно?
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
05.08.2014, 19:33
Цитата Сообщение от pav1uxa Посмотреть сообщение
Как можно сделать чтобы все было последовательно?
Они ы выполняются последовательно. Только быстро.
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
05.08.2014, 20:59  [ТС]
Цитата Сообщение от insite2012 Посмотреть сообщение
Они ы выполняются последовательно. Только быстро.
и не последовательно и не быстро...
Цитата Сообщение от pav1uxa Посмотреть сообщение
Что я ожидаю: в листбоксе появляется цифра 1, далее идет подключение к фтп, там выполняются необходимые действия, по окончании в листбоксе появляется цифра 2.
Что я получаю: идет подключение к фтп, там выполняются необходимые действия, по окончании в листбоксе появляется цифра 1 и сразу же цифра 2.
Добавлено через 5 минут
Ну вот еще проще пример:
C#
1
2
3
4
5
6
        private void button1_Click(object sender, EventArgs e)
        {
            listBox1.Items.Add("Hello");
            System.Threading.Thread.Sleep(5000);
            listBox1.Items.Add("world!");
        }
По логике после нажатия на кнопку в листбоксе должна появиться строка Hello и через 5 секунд строка world. По факту же - после нажатия на кнопку 5 секунд программа просто висит, а потом одновременно появляются 2 строки - Hello и world...
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
05.08.2014, 21:02
Цитата Сообщение от pav1uxa Посмотреть сообщение
и не последовательно и не быстро...
Да ну... Вы просто не понимаете... Вы пытаетесь получить (замечу, синхронным методом!) ответ от сервера, вот у вас ничего и не появляется в листбоксе. Используйте BeginGetResponse-EndGetResponse, или в отдельном потоке.
И тогда все появится.
0
Кодогенератор
 Аватар для hepper
200 / 200 / 51
Регистрация: 15.06.2011
Сообщений: 794
05.08.2014, 21:02
Цитата Сообщение от pav1uxa Посмотреть сообщение
потом одновременно появляются 2 строки
в самом лист боксе они появляются в верном порядке, а вот на экране появляются так как вы видите, т.е. поток этот вы усыпляете.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
05.08.2014, 21:04
Цитата Сообщение от pav1uxa Посмотреть сообщение
По логике после нажатия на кнопку в листбоксе должна появиться строка Hello и через 5 секунд строка world.
По вашей логике - может и так. А вот по логике работы кода - не появится там ничего до окончания Sleep-а.
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
05.08.2014, 23:30  [ТС]
Цитата Сообщение от insite2012 Посмотреть сообщение
Вы пытаетесь получить (замечу, синхронным методом!) ответ от сервер
кстати я заметил, что долго он думает даже не из за того что подключается к фтп. если я один и тот же запрос буду выполнять несколько раз подряд (при этом каждый раз отключаясь и подключаясь по новой), то задержка будет только после первого раза, почему то.
Цитата Сообщение от insite2012 Посмотреть сообщение
По вашей логике - может и так. А вот по логике работы кода - не появится там ничего до окончания Sleep-а.
Это все прекрасно, и я уже давно заметил что логика исполнения кода отличается от моей (с этого я кажется и начал тему). Вопрос в том, как хотябы на этом простом примере из 3х строк сделать так как я хочу? Неужели для такого простого примера придется использовать Thread'ы или BackgroundWorkerы?
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
05.08.2014, 23:34
Цитата Сообщение от pav1uxa Посмотреть сообщение
Неужели для такого простого примера придется использовать Thread'ы или BackgroundWorkerы?
pav1uxa,
Цитата Сообщение от insite2012 Посмотреть сообщение
Используйте BeginGetResponse-EndGetResponse
На MSDN есть хорошие примеры по данному вопросу.
И разве использовать потоки так сложно?
1
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
06.08.2014, 10:25  [ТС]
Цитата Сообщение от insite2012 Посмотреть сообщение
Используйте BeginGetResponse-EndGetResponse
Я имел ввиду этот простой пример
C#
1
2
3
4
5
6
private void button1_Click(object sender, EventArgs e)
* * * * {
* * * * * * listBox1.Items.Add("Hello");
* * * * * * System.Threading.Thread.Sleep(5000);
* * * * * * listBox1.Items.Add("world!");
* * * * }
ну да ладно не важно.
Цитата Сообщение от insite2012 Посмотреть сообщение
И разве использовать потоки так сложно
я не понимал как там использовать функции с параметрами (а не процедуры). сейчас почитал, понял что вроде как можно через Thread.Start() передавать параметры в исполняемую функцию. хорошо, а как можно засунуть в Thread создание класса? Например есть строка
C#
1
MyClass mclass = new MyClass();
Конструктор класса исполняется долго, как можно засунуть эту строку в Thread, не меняя самого класса? Нужно mclass сделать глобальным, засунуть его в процедуру, а процедуру в Thread?..
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
06.08.2014, 10:36
pav1uxa, по вашему простому примеру вот вам пример как работает. Всего несколько строк кода...
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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
using System.Threading;
using System.Threading.Tasks;
 
namespace WindowsFormsApplication8
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Load += (s, e) =>
                {
                    listBox1.Items.Add("Hello ");
                    Task.Factory.StartNew(() =>
                        {
                            Thread.Sleep(5000);
                            this.Invoke((Action)delegate() { listBox1.Items.Add("World!"); });
                        });
                };
        }
    }
}
Дальше,
Цитата Сообщение от pav1uxa Посмотреть сообщение
функции с параметрами (а не процедуры)
В шарпе принятое определение - методы, с параметрами, без параметров, без разницы.
Цитата Сообщение от pav1uxa Посмотреть сообщение
Конструктор класса исполняется долго, как можно засунуть эту строку в Thread, не меняя самого класса?
В отдельном потоке создайте экземпляр класса, в чем проблема?
1
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
06.08.2014, 16:24
C#
1
2
3
4
BackgroundWorker bw = new System.ComponentModel.BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += (s, e)=>{for(int i=2; i<100;i++) { Thread.Sleep(500); (s as BackgroundWorker).ReportProgress(i);}};
bw.ProgressChanged += (ss, ee)=> label1.Invoke(new Action<int>(value=>label1.Value = value), ee.ProgressPercentage);
1
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
06.08.2014, 16:58  [ТС]
Цитата Сообщение от insite2012 Посмотреть сообщение
this.Load += (s, e) =>
воу, какие то новые для меня символы... спасибо, буду разбираться
0
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
06.08.2014, 17:55
pav1uxa, это лямбда-выражение
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
06.08.2014, 18:16
Learx, насколько я знаю, при обработке события ProgressChanged (так же как и RunWorkerCompleted) нет необходимости маршалинга в основной поток UI (а вот при обработке DoWork это необходимо).
1
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
06.08.2014, 18:20
Лол, и никто не объяснил суть. Ладно. Возмем самое простое:
Цитата Сообщение от pav1uxa Посмотреть сообщение
C#
1
2
3
4
5
private void button1_Click(object sender, EventArgs e)
{ 
    listBox1.Items.Add("Hello");
    System.Threading.Thread.Sleep(5000);
    listBox1.Items.Add("world!"); * * * * }
На уровне работы ОС с окнами это выглядит где-то так:
- в очереди сообщений появляется Click по кнопке;
- хватаем это сообщение и обрабатываем;
- меняем значения в листе. Это автоматом помечает его "на перерисовку" добавляет Paint в очередь;
- т.к. вся эта очередь находится в одном потоке, то пока не закончится Click, то Paint не начнет выполнение.
- снова меняем значение в листе. Он всё ещё не перерисован, а значит дублировать Paint не будет.
- Click завершило выполнение, теперь вызывается Paint и перерысовывает лист по его текущему состоянию.

Не по теме:

P.S. В свое время по незнанию этого напоролся на колизию связанную с ивоками. Блочил ресурс в бэкграунде, основной останавливался. В бэкграунде вызывал синхроный инвок и всё -- прога стала, т.к. основной поток стоит, а вторичный ждет завершения инвока. >_<

0
1057 / 864 / 195
Регистрация: 31.03.2010
Сообщений: 2,521
06.08.2014, 18:24
insite2012, точно, на то он и нужен BackgroundWorker ...
C#
1
 bw.ProgressChanged += (ss, ee) =>  label1.Text = ee.ProgressPercentage.ToString();
1
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
06.08.2014, 18:25
Learx, точно, на RSDN три части про потоки, классная вещица, зачитаешься.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.08.2014, 18:25
Помогаю со студенческими работами здесь

Выполнение определенных операций в отдельном потоке
Во время выполнения кода форма, ясное дело, зависает и ожидает завершения операций. Мне необходимо сделать так, чтобы с формой можно было...

Выполнение определенных операций в отдельном потоке
Здравствуйте, только начал писать на c# wpf . Затруднялся с пониманием асинхроные потоки. Суть вопроса: по клику на кнопку происходит вызов...

Проблема с отображением элементов WPF окна на момент длительных операций в коде
Доброго времени суток, помогите пожалуйста, Есть функция, на отработку которой уходит примерно 3-5 минут. На это время приложение...

Как оценить время затраченное на выполнение длительных операций
Всем здравствуйте. Как точно (миллисекунды) и грамотно оценить интервал времени, затраченный на выполнение, например, следующего...

Выполнение в отдельном потоке
Необходимо реализовать выполнение данного класса в отдельном потоке. У меня никак не выходит, прошу помощи) import java.awt.Color; ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru