Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

C#. ProgressBar в потоке заполняется не параллельно процессу вычислений

244
14 сентября 2010 года
UAS
2.0K / / 19.07.2006
Вообщем, проблема в следующем. Реализовал алгоритм шифрования ГОСТ. Шифруется не по блокам (как в стандарте), а по раундам (так надо). После окончания каждого раунда (всего 32) необходимо выводить промежуточную информацию: заполняется один textBox(multilne) и progressBar. Проблема в том, что textBox заполняется корректно - после каждой итерации добавляется строчка, а progressBar как будто сам по себе - т.е. он сразу заполняется до 100%.

Код:
Код:
// содержимое события onClick по кнопке
....

Control.CheckForIllegalCrossThreadCalls = false;

Gost_28147 gost = new Gost_28147();
gost.OnRoundFinish += delegate(Gost_28147_RoundFinishParams round_parameters) {
    //textBox
    encryption_process_log.Text += "sometext here" + "\r\n";

    // progressBar
    progressBar_encryption.Value = 100*(int)Math.Ceiling((double)round_parameters.Round / 32);
};

// Результат зашифровки
List<byte> result = new List<byte>();

// запуск потока
Thread t = new Thread(delegate() {
    result = gost.Crypt(text2crypt); // text2crypt - это List<byte>
});
t.Start();
t.Join(); // т.к. ниже надо записать в файл содержимое result

....


OnRoundFinish - событие, вызываемое при окончании раунда шифрования.

В итоге, если взять большой открытый текст (для шифрования) (или добавить Thread.Sleep() в OnRoundFinish), то textBox заполняется пропорционально выполненным раундам, а progressBar так же заполняется частями (т.е. x/32), но делается это практически мгновенно за один-два раунда.

Control.CheckForIllegalCrossThreadCalls = false; - не причем (я его здесь поставил для наглядности кода, чтобы избавиться от делегатов и т.д.). Я также пробовал через делегаты и InvokeRequired/BeginInvoke - результат тот же самый.

P.S.: в целом, это мой первый опыт с дотнет, потому может чего-то не понимаю, т.к. в других языках подобное у меня работало, как задумано.
P.S.2: WinForm, .Net Framework 3.5
5
14 сентября 2010 года
hardcase
4.5K / / 09.08.2005
Чему равны progressBar_encryption.MinValue и progressBar_encryption.MaxValue?

(з.ы. для фоновых задач есть комопонента BackgroundWorker)
(з.з.ы для операций с потоками данных лучше использовать Stream-ы)
5
14 сентября 2010 года
hardcase
4.5K / / 09.08.2005
Проблема в
 
Код:
100*(int)Math.Ceiling((double)round_parameters.Round / 32)

По-умолчанию MaxValue у прогресс-бара равен 100, а это выражение будет возвращать либо 0, либо 100, посему прогресс бар будет всегда показывать пустоту либо заполненность.
244
14 сентября 2010 года
UAS
2.0K / / 19.07.2006
Тьфу блин. Спс хардкейсу и kosfiz.
Вчера ночью, когда писал, юзал Math.Ceiling, и что-то ночью я подумал, что вот это высчитывание Value для прогрессбара верное, потому и не брал в расчет.
А Math.Ceiling что делает? Округляет до большего целого, т.е. до 1, а 1*100 всегда 100.

Вообщем, сам виноват, всем спасибо=)

P.S. про бэкграунд воркер почитаю.
5
14 сентября 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: UAS
Вообщем, сам виноват, всем спасибо=)


У тебя 32 раунда?
Вот и ставь прогресс-бару MaxValue = 32, а Value - номером этого раунда (+1, если они с нуля).

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог