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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> UserControl и многопоточность 
:(
    Опции темы
3she1on
Дата 17.12.2008, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте! Пишу сейчас свой контрол Ticker (бегущая строка) под dotNet CF. Есть небольшой вопрос. Вот приблизительный код контрола (не законченная версия):

Код

public partial class Ticker : UserControl
    {
        String textToView = String.Empty;
        int delay = 200;


        public UserControl1()
        {
            InitializeComponent();
        }

        public String TextToView
        {
            set { textToView = value;  }
            get { return textToView; }
        }

        public int Delay
        {
            set { delay = value; }
            get { return delay; }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            int x, y;
            x = 0;
            y = 2;
            Graphics g = e.Graphics;
            if (!textToView.Equals(String.Empty))
            {
                for (int i = 0; i < 20; i++)
                {
                    g.Clear(this.BackColor);
                    g.DrawString(textToView, this.Font, new SolidBrush(this.ForeColor), x, y);
                    x++;
                    Thread.Sleep(delay);
                }
            }
        }
    }


Когда юзаю контрол в приложениях происходит следующее: сам тикер рисует себя корректно, но при этом блокируется контейнер (форма, на которой лежит тикер). Когда внутри OnPaint класса Ticker цикл отрисовки проходит все итерации - управление нормально передается контейнеру (форме).

Контрол лепил вот так:

Код

public partial class Form1 : Form
    {
        delegate void initTicker();
        Ticker ticker;
        public Form1()
        {
            InitializeComponent();
            Thread t = new Thread(new ThreadStart(initializeTick));
            t.Start();
            t.Join();
        }

        private void initializeTick()
        {
            initTicker tickDelegate = new initTicker(addTick);
            this.Invoke(tickDelegate);
        }


        private void addTick()
        {
            ticker = new Titcker();
            ticker.TextToView = "this is ticker text";
            this.Controls.Add(ticker);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("bla bla bla!");
        }
    }


Хотелось бы узнать как заставить их рисовать себя асинхронно. Заранее благодарен
PM MAIL   Вверх
Partizan
Дата 17.12.2008, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

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



3she1on

надо саму процедуру отрисовки тикера в отдельный поток вынести...

То есть вот этот код - неплохо бы вынести в отдельный поток...
Код

           int x, y;
            x = 0;
            y = 2;
            Graphics g = e.Graphics;
            if (!textToView.Equals(String.Empty))
            {
                for (int i = 0; i < 20; i++)
                {
                    g.Clear(this.BackColor);
                    g.DrawString(textToView, this.Font, new SolidBrush(this.ForeColor), x, y);
                    x++;
                    Thread.Sleep(delay);
                }
            }



--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
amarenkov
Дата 18.12.2008, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



, а, поскольку, после этого получишь несколько ошибок, рисование во втором потоке надо производить на какой-нибудь Bitmap, созданный в том же потоке. А вот отрисовку на форму (т.е. в главный поток) придется синхронизировать и просто уже отрисованный Bitmap копировать на e.Graphics.
PM MAIL ICQ   Вверх
masterik
Дата 29.12.2008, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 28.8.2006
Где: Остенд, Бельгия

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



  •  Попробуй высчитывать координаты в отдельном потоке и вызывать оттуда обновление формы/контрола (Control.Invalidate), а в обработчике OnPaint только/уже рисовать на нужные/готовые координаты. Здесь также идеально подходит класс System.Windows.Forms.Timer.

    И как заметил amarenkov, чтобы избежать ошибок возможно придется воспользоваться парой Control.InvokeRequired и Control.Invoke.

  •  Не совсем понял логику "лепки" твоего контрола на форму.......
    Зачем делать это в отдельном потоке, когда ты все равно дожидаешься завершения работы потока (Thread.Join)?


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

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


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

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


 




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


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

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