Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 08.02.2014
Сообщений: 57

Backgroundworker.IsBusy всегда true

08.06.2015, 00:07. Показов 3337. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В общем, есть метод, который должен делать дела, ждать секунду и продолжать делать дела.
В нем я вызываю BackgroundWorker, в котором жду секунду, ВРОДЕ КАК завершаю работу потока и выхожу дальше.
Выбрал самый наибанальнейший вариант, потому что пробовал по-разному - не получалось.

Код:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        
        public void Animate()
        {
            Solver s = new Solver(_desk);
            foreach (var item in s.Solution)
            {
                //Делаем дела
                _form.Update();
                _form.backgroundWorker1.RunWorkerAsync();
           }
        }
    }
 
...     public void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            BackgroundWorker bw = sender as BackgroundWorker;
            e.Cancel = true;
            Thread.Sleep(1000);
        }
Но нифига, IsBusy все еще true после выполнения
C#
1
e.Cancel = true;
Насколько я понимаю, именно так нужно закрывать поток?

Тыкните ошибку, пожалуйста:С
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.06.2015, 00:07
Ответы с готовыми решениями:

XML, Свойство HasChildNodes всегда возвращает true
Добрый день! Помогите разобраться с XML есть простой файл XML: <?xml version="1.0" encoding="utf-8"?> <Страна...

BackgroundWorker
Есть 10 button-ов и 1 backgroundWorker. При нажатии на любой button должен запускаться поток, в котором анализируется от какого button-а...

BackgroundWorker
Можно ли определить ProgressChanged для всех BackgroundWorker`ов? Или как осуществить подобное?

17
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
08.06.2015, 01:48
Что-то я не пойму в чем проблема.. вы хотите просто подождать, для этого используете BackgroundWorker? Если так-у него есть событие RunWorkerCompleted, в нем и делайте все то, что надо делать по завершению. Поток сам нормально завершается, если уж надо его прервать, то:
C#
1
bw.CancelAsync();
А это:
C#
1
e.Cancel = true;
Обычно отменяет дальнейшую обработку события, в данном случае это скорее всего вообще ничего не даст. Это удобно ,к примеру, для запрета закрывать форму. Может быть проще весь код с ожиданиями запустить в отдельном потоке, и ждать там сколько душе угодно?
0
0 / 0 / 0
Регистрация: 08.02.2014
Сообщений: 57
08.06.2015, 02:05  [ТС]
Если я правильно понимаю,
C#
1
bw.CancelAsync();
только изменяет состояние CancelationPending, которое мы уже должны ловить и закрывать поток.

Ну да ладно. Я попробовал сделать так, как я вас понял: убрал вообще все из DoWork, а RunWorkerCompleted вот
C#
1
2
3
4
5
6
7
       
         private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            BackgroundWorker bw = sender as BackgroundWorker;
            Thread.Sleep(1000);
            bw.CancelAsync();
        }
Теперь я получаю "Этот компонент BackgroundWorker занят и не может одновременно выполнять несколько задач.", то есть мы не вошли/не успели войти в Completed.
Попробовал добавить после запуска фонового потока цикл
C#
1
while (_form.backgroundWorker1.IsBusy) { }
Получил зацикливание, то есть Completed вообще не вызвался.

Добавлено через 1 минуту
Смысл всего именно в том, чтобы после каждой итерации форича ждать секунду и продолжать работу.

Добавлено через 3 минуты
Прочел:
DoWorkEventArgs.Cancel не вызывает остановку, а только говорит, что нет смысла обращаться к результатам работы потока
CancelAsync - зажигает свойство CancelationPending, изменение которого нужно обработать. Но так как я знаю точно, что я закрываю сразу после паузы поток, не вижу смысла использовать его.

И вообще я уже ничерта не понимаю.
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
08.06.2015, 02:11
Ну да ладно. Я попробовал сделать так, как я вас понял: убрал вообще все из DoWork, а RunWorkerCompleted вот
Я имел в виду совсем не это....
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace WindowsFormsApplication58
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.backgroundWorker1.RunWorkerAsync();
        }
 
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bw = sender as BackgroundWorker;
            bw.CancelAsync(); //если это закомментировать-текст лейбла меняется через секунду, а так-мгновенно
            Thread.Sleep(1000);
        }
 
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            label1.Text = "готово";
        }
    }
}
Как получается, что он зацикливается у вас пока что не понимаю, вроде же все тут просто... В вашем случае я бы весь цикл foreach или вообще метод Animate запихал в отдельный поток.
0
0 / 0 / 0
Регистрация: 08.02.2014
Сообщений: 57
08.06.2015, 02:28  [ТС]
То есть мне нужно весь код, который я выполняю в фориче запихать в обработку Completed'a?

Добавлено через 9 минут
Я всего лишь хотел заставить программу ждать одну секунду, блин.

Ладно, попробую пошаманить. Спасибо:3
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
08.06.2015, 02:34
CancelAsync - зажигает свойство CancelationPending, изменение которого нужно обработать.
Да, глянул внимательно-действительно так. Но ,как видно,внутри DoWork этот метод работает по-другому, хотя вместо него с тем же успехом можно было написать return, изменились бы только не важные в данном коде свойства.
То есть мне нужно весь код, который я выполняю в фориче запихать в обработку Completed'a?
Ну там не видно весь код, может только сам foreach, а может и весь метод, смотря что он содержит. И не Completed, а DoWork.
0
0 / 0 / 0
Регистрация: 08.02.2014
Сообщений: 57
08.06.2015, 02:41  [ТС]
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
        
       private void BwOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs)
        {
            int item = (int) runWorkerCompletedEventArgs.Result;
            var zeroIndex = Array.FindIndex(_desk.Array, q => q == 0);
            var itemIndex = Array.FindIndex(_desk.Array, q => q == item);
            _desk.SetElement(zeroIndex / 4, zeroIndex % 4, item);
            _desk.SetElement(itemIndex / 4, itemIndex % 4, 0);
            ShowDesk(zeroIndex, itemIndex);
        }
 
        private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
        {
            BackgroundWorker curBackgroundWorker = sender as BackgroundWorker;
            bw.CancelAsync();
            int item = (int?) doWorkEventArgs.Argument ?? 0;
            doWorkEventArgs.Result = item;
            Thread.Sleep(1000);
        }
 
        public void ShowDesk(int index1, int index2)
        {
            var i = 0;
            foreach (Button b in _field)
            {
                b.Text = _desk.Array[i].ToString();
                i++;
            }
           _form.Controls[_field[index1].Name].Invalidate();
           _form.Controls[_field[index1].Name].Invalidate();
 
        }
 
        public void Animate()
        {
            Solver s = new Solver(_desk);
            foreach (var item in s.Solution)
            {
                bw.RunWorkerAsync(item);
                _form.Update();
           }
        }
Теперь это выглядит так, и я все еще не очень.
Фоновый поток не успевает видимо выполниться, и я получаю "Этот компонент BackgroundWorker занят и не может одновременно выполнять несколько задач"

Не успел прочесть про то, что должно быть в DoWork, сейчас переделать попробую. Но я не понимаю, что тогда должно быть в Completed.

Добавлено через 4 минуты
В любом случае, Completed не зажигается.
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
08.06.2015, 02:46
C#
1
2
3
4
5
           foreach (var item in s.Solution)
            {
                bw.RunWorkerAsync(item);
                _form.Update();
           }
Такая конструкция не может работать, вы пытаетесь 1 и тот же воркер много раз запускать поток... Весь foreach или весь метод Animate надо в отдельный поток, и создать его только 1 раз. Если надо обращаться к чему-то с формы из другого потока-для этого есть Invoke/BeginInvoke.
0
0 / 0 / 0
Регистрация: 08.02.2014
Сообщений: 57
08.06.2015, 02:48  [ТС]
То есть я создаю поток с анимацией и уже внутри него создаю фоновый поток с ожиданием?
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
08.06.2015, 02:56
Да, глянул внимательно-действительно так. Но ,как видно,внутри DoWork этот метод работает по-другому, хотя вместо него с тем же успехом можно было написать return, изменились бы только не важные в данном коде свойства.
Тут я не прав-дело оказывается в том, что воркер не выбрасывает исключения, когда что-то не так в обработчике DoWork, а просто молча завершает его, проставляя в RunWorkerCompletedEventArgs что он завершился ошибкой. Обычно пользуюсь Threadами, туплю Соответственно bw.CancelAsync(); в моем коде элементарно выбрасывал исключение.

Добавлено через 7 минут
То есть я создаю поток с анимацией и уже внутри него создаю фоновый поток с ожиданием?
А откуда взялся "поток с анимацией"? У вас метод Animate уже вызывается в отдельном потоке?
0
0 / 0 / 0
Регистрация: 08.02.2014
Сообщений: 57
08.06.2015, 02:59  [ТС]
Не, я просто сразу учел то, что вы сказали, что анимацию в поток надо бы запихать.

Но я создал этот самый поток, а где объявлять-то фоновый поток, получается?
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
08.06.2015, 03:06
Ну первое, что мне пришло бы в голову при виде такой задачи, это весь метод Animate() запустить через поток типа Thread, а форму обновлять как-то так:
C#
1
_form.BeginInvoke(new Action(delegate { _form.Update(); }));
Если я конечно правильно понял задачу. Можно делать то же самое через воркер-разница не велика. Важно, чтобы все действия, требующие ожидания, выполнялись в отдельном потоке и не вешали форму.
0
0 / 0 / 0
Регистрация: 08.02.2014
Сообщений: 57
08.06.2015, 03:09  [ТС]
Спасибо большое, начну пробовать тогда:3
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
08.06.2015, 03:14
с Solver и _desk надо только было бы определиться, их не видно чтобы точно сказать как именно(

Добавлено через 1 минуту
Скиньте проект, гляну
0
0 / 0 / 0
Регистрация: 08.02.2014
Сообщений: 57
08.06.2015, 03:16  [ТС]
Да ладно, время отнимать не хочу, итак столько уже потратили
0
08.06.2015, 03:20

Не по теме:

Это не страшно:)

0
0 / 0 / 0
Регистрация: 21.04.2015
Сообщений: 1
11.11.2015, 10:29
Если я правильно понял задачу (перезапуск воркера в цикле), то чтобы он не входил в ступор (а он всегда будет занят если поставить проверку While(!IsBusy){}) нужно добавить в этот цикл Application.DoEvents();:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
foreach (string s in uFiles)
{
      while (bgw.IsBusy)
      {
           Application.DoEvents();//Без этой строки осн. поток все время занят, поэтому событие *_RunWorkerCompleted не сработает никогда
           if (hasError)
           {
                 MessageBox.Show("Произошла ошибка при загрузке файла обновлений!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                  //Write log!
                  return;
           }
       }
       if (!bgw.IsBusy)
       {
            this.Text = "Загрузка обновления: " + updName;
            bgw.RunWorkerAsync(updName);
       }               
}
Если еще актуально ...а может, еще кому понадобится (я 3 дня искал решение).
0
979 / 874 / 350
Регистрация: 26.04.2012
Сообщений: 2,647
11.11.2015, 12:11
А зачем, если не секрет, нужна такая конструкция?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.11.2015, 12:11
Помогаю со студенческими работами здесь

использование backgroundworker
Здравствуйте! У меня имеется некоторая задача.......есть файлы больших размеров, нужно их открывать, чтобы не было зависаний и потом в...

2 BackgroundWorker параллельно
Один BackgroundWorker пускаю на копирование файлов. Второй на запись этих файлов в базу. bgUnZipToFtp.RunWorkerAsync(); ...

backgroundWorker и формы...
Для работы с потоками использую backgroundWorker. Есть два вопроса.. 1. На первой форме использую выделенный поток под фоновую...

Проблемы с BackgroundWorker
Вот уже целый день Пытаюсь разобраться с BackgroundWorker и попытки тщетны. Суть задачи, Имеется Windows Form интерфейс и отдельный класс...

Таймер в Backgroundworker
Как сделать таймер в background worker ? Пытался сделать нормальный таймер обратного отсчета в System.Timer.Timers получается слишком...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru