Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Зависание окна при объемной цикличной работе. Окно полностью виснет, даже с потоком. 
V
    Опции темы
tolan96
Дата 4.1.2011, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 22.12.2009

Репутация: нет
Всего: нет



С новым годом, товарищи.  smile  

Имеем:
1) Окно
2) На нем ProgressBar
3) Большую и сложную функцию, которая изменяет параметр Value нашего ProgressBar'а.
4) Поток, выполняющий эту большую и сложную функцию, который был создан специально, чтобы окно не висло.
5) Окно виснет.

Примерный код:
Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Threading;

namespace MyNamespace
{
    public partial class MyClass : Form
    {
        delegate void Process();

        public Parsing()
        {
            InitializeComponent();
            Thread.CurrentThread.Priority = ThreadPriority.Highest; // Даю окошку приоритет повыше, чтобы оно не висло.
            Thread t = new Thread(new ThreadStart(Function));      
            t.Priority = ThreadPriority.Lowest;                                   // Даю потоку приоритет поменьше, чтоб он не вешал окошко.
            t.Start();
        }

        private void Function()
        {
            if (label3.InvokeRequired)
            {
                Process p = new Process(Function);
                this.Invoke(p);
            }
            else
            {
                string[] files = Directory.GetFiles(tbDirectoryPath.Text, "*.*"); // Берем все файлы из директории, указанной в TextBox'е
                string content = File.ReadAllText(files[0]);                                // Читаем один файл для последующего получения кодировки
                Encoding encoding = FindEncoding(content);                           // Получаю кодировку с помощью мною сделаной функцией

                int count = 0;
                
                foreach (string file in files)                                   // Поочередно получаем имена всех найденных файлов
                {
                    content = File.ReadAllText(file, encoding);       // Читаем содержимое файла
                    string result = BuildResult(content);                // Обрабатываем содержимое и получаем результат с помощью моей функции
                    File.AppendAllText("Otchet.txt", result + Environment.NewLine, encoding);     // Пишем в файл новою строку с результатом
                    count++;
                    label3.Text = count.ToString();                         // Отображаем с помощью лейбла количество обработанных файлов
                    progressBar1.Value = (int)(((double)(double)count / (double)files.Length) * 100);      // Меняем значение ProgressBar'а
                }
            }
        }
    }
}



Тоесть мне всего-то навсего нужно, чтобы ProgressBar отображал прогресс обработки, и окошко при этом не висло...
Почему оно виснет? Вся сложная работа ведь в отдельном потоке!

Дяденьки, помогите!!!  smile 

P.S. Слышал про BackgroundWorker, но пока еще не смотрел что он из себя представляет.
PM MAIL   Вверх
KelTron
Дата 4.1.2011, 21:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 5
Всего: 38



Вот тебе пример с BackgroundWorker-ом

Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  WindowsFormsApplication1.zip 42,91 Kb


--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
tolan96
Дата 4.1.2011, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 22.12.2009

Репутация: нет
Всего: нет



Цитата

Вот тебе пример с BackgroundWorker-ом 

Что-то не качается.
Цитата

Сообщение Форума
Обнаружена ошибка:

Эта функция запрещена для Гостей

Странно, я же не гость...

Вообщем, как я понял мне всё-таки нужно изучить BackgroundWorker. И будет мне счастье!
PM MAIL   Вверх
Kaerus
Дата 4.1.2011, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


WPF'er
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 3.9.2010

Репутация: нет
Всего: 1



tolan96
Честно твой код бред какой-то:
  • Ты создаешь фоновый поток для Function
  • В нем проверяешь что ты НЕ в потоке окна и по этому
    Код

    if (label3.InvokeRequired)
    {
    ...
    }
  • Передаешь долгую функцию в поток окна и она в нем выполняется
    Код

    Process p = new Process(Function);
    this.Invoke(p);
Круг замкнулся)) ты начал в рабочем потоке и в нем же кончил

Это сообщение отредактировал(а) Kaerus - 4.1.2011, 21:58
PM MAIL ICQ   Вверх
tolan96
Дата 4.1.2011, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 22.12.2009

Репутация: нет
Всего: нет



Цитата

Честно твой код бред какой-то:

 smile  Учусь работать с потоками.

Делал всё по примеру с MSDN... 

Если вам не трудно, можете привести код, с правильной реализацией?  smile 

Это сообщение отредактировал(а) tolan96 - 4.1.2011, 22:00
PM MAIL   Вверх
Kaerus
Дата 4.1.2011, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


WPF'er
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 3.9.2010

Репутация: нет
Всего: 1



ПРИМЕР:
Код

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        Thread.CurrentThread.Priority = ThreadPriority.Highest;

        var t = new Thread(Function) { Priority = ThreadPriority.Lowest };
        t.Start();
    }

    private void Function()
    {
        string[] files = Directory.GetFiles(tbDirectoryPath.Text, "*.*"); // Берем все файлы из директории, указанной в TextBox'е
        string content = File.ReadAllText(files[0]);                                // Читаем один файл для последующего получения кодировки
        Encoding encoding = FindEncoding(content);                           // Получаю кодировку с помощью мною сделаной функцией
        int count = 0;
        foreach (string file in files)                                   // Поочередно получаем имена всех найденных файлов
        {
            content = File.ReadAllText(file, encoding);       // Читаем содержимое файла
            string result = BuildResult(content);                // Обрабатываем содержимое и получаем результат с помощью моей функции
            File.AppendAllText("Otchet.txt", result + Environment.NewLine, encoding);     // Пишем в файл новою строку с результатом
            count++;

            Invoke((Action<int, int>)(
                (c, p) =>
                {
                    label3.Text = c.ToString();
                    progressBar1.Value = p;
                }),
                count, (int)(100.0 * count / files.Length));
        }
    }


Это сообщение отредактировал(а) Kaerus - 4.1.2011, 22:28
PM MAIL ICQ   Вверх
tolan96
Дата 4.1.2011, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 27
Регистрация: 22.12.2009

Репутация: нет
Всего: нет



Спасибо Kaerus.

Я, кстати, только что сделал всё с помощью BackgroundWorker'а.
Но теперь появилась новая проблема  smile ...

Поток никак не хочет останавливаться. Скажем, при нажатии на кнопку "Отмена" происходит следущее:
Код

            backgroundWorker1.CancelAsync();
            backgroundWorker1.Dispose()
            this.Close();

Я так понимаю, что backgroundWorker1 должен "Отмениться" и потом "Раствориться". Но он остается. Так, когда я снова создаю экземпляр дочернего окна, он создает еще один поток, а потом еще и еще. В итоге они начинают драться за доступ к файлу, одновременно пихать в него кучу данных, отчего размер файла растёт как на дрожжях.

Как же всё таки убивается этот backgroundWorker1 перед закрытием дочернего окна?

---------------------------------------------------------------------------------------------------------------------------------

Оказалось, что он сидя в цикле foreach() отказывался из него вылезать. Пришлось сделать это принудительно...
Код

foreach (string file in files)
                {
                    if (worker.CancellationPending)
                    {
                        e.Cancel = true;
                        break;                                                          // Вот тут обрываем цикл.
                    }
                    content = File.ReadAllText(file, encoding);
                    string result = parent.BuildResult(content);
                    File.AppendAllText("Otchet.txt", result + Environment.NewLine, encoding);

                    count++;
                    label3.Text = count.ToString();
                    int percentage = (int)(((double)(double)count / (double)files.Length) * 100);
                    
                    worker.ReportProgress(percentage);
                }


В итоге всё сделано с помощью BackgroundWorker'а и работает так как надо. Ну, почти...

Спасибо всем за помощь!!!  smile 

Это сообщение отредактировал(а) tolan96 - 4.1.2011, 23:54
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.1701 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.