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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование делегата для ProgressBar, Как? 
V
    Опции темы
MasterOfCode
Дата 15.10.2008, 08:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


elwin
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 24.4.2008
Где: World.Russia.Tyum en

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



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

У меня есть класс, который работает с БД. Есть процедура у класса, которая перекачивает данные из одной БД в другую. Есть цикл в процедуре в ходе которого должен изменяться ProgressBar.Position. Подскажите, необходимо ли в данном случаи использовать делегат. Если да, то как, т.е. в каком месте его объявить и как использовать? 
Или же лучше просто ссылку на контрол в процедуру передать и все? 


--------------------
user posted image
PM ICQ   Вверх
elbjarn
Дата 15.10.2008, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(MasterOfCode @  15.10.2008,  08:18 Найти цитируемый пост)
Или же лучше просто ссылку на контрол в процедуру передать и все?  

ни в коем случае. во-первых, кросстредовые обращения к контролам небезопасны. вы можете работать с контролом только в контексте того потока, в котором он был создан. для доступа к нему из других потоков, вы должны вызвать делегат из "родного" ему потока, чтобы ваш поток был приостановлен на какое-то время, а родной поток смог выполнить работу с контролом.
Код

public delegate void ProgressChanged(int progress);
    
    public class MyThread
    {
        public ProgressChanged pc = null;
        public void Start()
        {
            int n = 1000;
            for (int i = 0; i < n; i++)
            {
                int progress = i * 100 / n;
                if (pc != null)
                    pc(progress);
                for (int j = 0; j < n; j++)
                    for (int k = 0; k < n; k++)
                    {
                        int a = 0;
                        a++;
                    }
            }
        }
    }


//где-то в форме
public partial class myForm : Form
{
  // ....
  public void DoIt()
 {
            MyThread mt = new MyThread();
            mt.pc = SetProgress;

            System.Threading.Thread thread = new System.Threading.Thread(mt.Start);
            
            thread.Start();
 }
  
public void SetProgress(int progress)
        {
            if (textBox1.InvokeRequired)
            {
                ProgressChanged pc = new ProgressChanged(SetProgress);
                textBox1.Invoke(pc, progress);
            }
            else
            {
                textBox1.Text = string.Format("Выполнено: {0}%", progress);
            }
        }
}


Добавлено @ 14:45
вызовы InvokeRequired и Invoke для контрола как раз-таки нужны для обеспечения нитебезопасности, а вот метод Start() я поместил в отдельный класс вместе с ссылкой на делегат просто для удобства, полями этого класса могут стать и другие переменные, которые вы захотите сделать доступными методу треда. вместо всего этого, кстати, можно было бы использовать просто параметризованный ThreadStart, т.е. такой, что ему передается при старте функции объект какого-то вашего класса, в который вы можете напихать все что угодно. это стандартный подход, пришел сюда из с++ и WinAPI программирования ([offtopic]там вновь создаваемый поток может получить LPVOID на какую-то область памяти, которую потом может попытаться интерпретировать как объект какого-то класса[/offtopic]), и его тоже часто используют.

Это сообщение отредактировал(а) elbjarn - 15.10.2008, 15:36
PM MAIL ICQ   Вверх
MasterOfCode
Дата 16.10.2008, 07:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


elwin
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 24.4.2008
Где: World.Russia.Tyum en

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



Код

public void SetProgress(int progress)


Когда его вызывать?


--------------------
user posted image
PM ICQ   Вверх
MasterOfCode
Дата 16.10.2008, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


elwin
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 24.4.2008
Где: World.Russia.Tyum en

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



Добавил 
Код

pc += new Form1.ProgressChanged(_frm.SetProgress);


Заработало. Только пришлось ссылку на форму передавать в мой класс. :(


--------------------
user posted image
PM ICQ   Вверх
MasterOfCode
Дата 16.10.2008, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


elwin
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 24.4.2008
Где: World.Russia.Tyum en

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



Прошу прощения. Затупил smile


--------------------
user posted image
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




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


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

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