Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.05.2010, 02:20   #1
Casper-SC
Форумчанин
 
Регистрация: 04.07.2007
Сообщений: 549
Восклицание Вывод сообщения в отдельном потоке и т.д.

Народ помогите мне, как вывести сообщение в отдельном потоке и так, чтобы я хоть 100 раз нажал кнопку, сто экземпляров запустилось в отдельном потоке. Я тут сидел думал и подумал что у меня всё получилось, оказалось нифига. Короче пытался в отдельном от своего проекте сделать этот вывод сообщения в отдельном потоке. Если найдутся желающие помочь, вот проект.

Главная форма

Код главной формы:

Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace MultiThreadApplication_ShowMessage
{
    public partial class FormMain : Form //переименуйте Form1 в FormMain
    {
        
        //Просто статичная ссылка используется в статическом методе
        public static FormMain MainForm; 

        Thread thr = new Thread(ShowMsg2); //новый поток

        //статичная строка сообщения, необходима лишь для статичного метода ShowMsg2
        public static String message = String.Empty; 

        //конструктор формы
        public FormMain()
        {
            InitializeComponent();
            MainForm = this; //статичной переменной присваиваем ссылку на главную форму
            thr.Start(); //запускаем отдельный поток
        }

        //обработчик нажатия по кнопке
        private void button1_Click(object sender, EventArgs e)
        {
            //присваиваем статичной переменной текст из поля куда пользователь ввёл текст
            message = this.richTextBoxMsg.Text;
            this.ShowMsg(); //выполняем метод ShowMsg
        }

        //Показать сообщение
        public void ShowMsg()
        {
            FormMessage formMessage = new FormMessage(message, this);
            formMessage.Show(); //показываем форму с сообщением
        }

        //по сути этот метод нужен лишь для демонстрации передачи
        //параметра конструктору this здесь не сработает
        public static void ShowMsg2()
        {
            FormMessage formMessage = new FormMessage(message, MainForm);
            formMessage.Show();
        }
    }
}

Форма сообщения

Код окна сообщения:
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MultiThreadApplication_ShowMessage
{
    public partial class FormMessage : Form //переименуйте Form2 в FormMessage
    {
        IWin32Window _Owner; //
        public FormMessage()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Конструктор с параметрами
        /// </summary>
        /// <param name="messageText">Текст сообщения</param>
        /// <param name="owner">Указатель на родителя формы</param>
        public FormMessage(String messageText, IWin32Window owner)
        {
            InitializeComponent();
            _Owner = owner;
            this.richTextBoxMsg.Text = messageText;
            this.richTextBoxMsg.SelectAll(); //выделить весь текст
            this.richTextBoxMsg.SelectionAlignment = HorizontalAlignment.Center; //выровнять по центру
        }

        private void button1_Click(object sender, EventArgs e) //и как заставить это работать?
        {
//            if (this._Owner is FormMain) //если родитель этой формы, главная форма, то...
//            {
//у свойства Modifiers компонента richTextBoxMsg должно быть выбрано public для доступа отсюда
//                (this._Owner as FormMain).richTextBoxMsg.Text = this.textBoxBackText.Text; 
//            }
            this.Close(); //закрываем окно с сообщением
        }
    }
}

Последний раз редактировалось Casper-SC; 11.05.2010 в 08:09.
Casper-SC вне форума Ответить с цитированием
Старый 12.05.2010, 19:05   #2
Casper-SC
Форумчанин
 
Регистрация: 04.07.2007
Сообщений: 549
По умолчанию

Может это просто не возможно? Просто столько народу посмотрело и никто не ответил. Может создать пустую форму в отдельном потоке, а она уже будет создавать окна с сообщениями, ну будет родителем. Так вариант сделать? Или есть способ лучше?
Или может просто создавать при каждом выводе сообщения новый поток?

И как из другого потока вернуть значение в основной поток?

И кстати как правильно останавливать поток?

Народ ну подскажите вообще не понимаю ничего пока, что в этих потоках, читал немного в MSDN, но там какие-то примеры замудрённые

Последний раз редактировалось Casper-SC; 12.05.2010 в 19:09.
Casper-SC вне форума Ответить с цитированием
Старый 12.05.2010, 19:26   #3
Cpluser
Форумчанин
 
Аватар для Cpluser
 
Регистрация: 16.02.2009
Сообщений: 555
По умолчанию

Постучи 597671952 помогу может!
Cpluser вне форума Ответить с цитированием
Старый 12.05.2010, 19:31   #4
Hollander
Участник клуба
 
Аватар для Hollander
 
Регистрация: 03.05.2007
Сообщений: 1,189
По умолчанию

Используй события.
Логика такая:
1. В главной форме создаешь некое событие и делегат
2. Создаешь 2-ую форму, в ней в отдельном потоке подписываешься на данное событие.(не забудь передать ссылку на 1-ую форму, чтобы иметь доступ к событию).
3. Когда надо вызываешь событие из 1-ой формы, а по вызову события - выводишь то, что надо на 2-ой.

Неплохая статья про события и делегаты: http://www.rsdn.ru/article/dotnet/delegat.xml
Hollander вне форума Ответить с цитированием
Старый 12.05.2010, 23:36   #5
Casper-SC
Форумчанин
 
Регистрация: 04.07.2007
Сообщений: 549
По умолчанию

Я сделал так:
Код:
        /// <summary>
        /// Запустить вывод сообщения на экран
        /// </summary>
        public  void RunMessage()
        {
               ShowMsg showMessage = new ShowMsg();
               switch (styleMsgForThr)
               {
                    case StyleMessage.Stiker:
                       {
                             showMessage.Stiker(SpType, frmSetting);
                             showMessage.formForShowing.Owner = this;
                        }
                        break;
                     .......................
                     .......................
                } 
        }
Код:
Thread thr = new Thread(RunMessage);
thr.Start();
То есть при выводе сообщения создаю поток. А при закрытии формы сообщения делаю это:
Код:
Thread.CurrentThread.Abort(); //убиваю поток... Интересно убивается ли

Последний раз редактировалось Casper-SC; 12.05.2010 в 23:49.
Casper-SC вне форума Ответить с цитированием
Старый 13.05.2010, 00:05   #6
Casper-SC
Форумчанин
 
Регистрация: 04.07.2007
Сообщений: 549
По умолчанию

А, нет! Что-то начало глючить эти потоки, программа выдаёт исключения, что поток был в процессе завершения... ошибка короче.
Я её исправил. Не в том месте завершал поток.

Если делать так:
Код:
        public  void RunMessage()
        {
            Invoke(new MethodInvoker(delegate
                {
                    ShowMsg showMessage = new ShowMsg();
                    switch (styleMsgForThr)
                    {
                        case StyleMessage.Stiker:
                            {
                                showMessage.Stiker(SpType, frmSetting);
                                showMessage.formForShowing.Owner = this;
                            }
                            break;
                    } 
                }
                ));
        }
То сообщение появляется и выезжает из-за экрана, но с тормозами (хотя, может мне кажется если и есть тормоза, то не значительные), так как я уже писал, запускается плеер. Что похоже подтверждает мои догадки, что сообщение выводится в том же потоке. А при закрытии формы завершается всё приложение.

Не выполнять этот метод думаю не выход, ведь приложение может и неделю не выключаться как и компьютер, и сколько будет тогда созданно потоков:
Код:
Thread.CurrentThread.Abort();
Как разрешить обращаться с одного потока к другому?

================

Всё работает! Просто проблема была в моём коде, а не в потоках. Например Thread.CurrentThread.Abort(); использовал не там где надо.

Последний раз редактировалось Casper-SC; 13.05.2010 в 02:19. Причина: Постоянно меняющаяся ситуация :)
Casper-SC вне форума Ответить с цитированием
Старый 18.05.2010, 02:24   #7
Arnezami
Форумчанин
 
Регистрация: 04.10.2009
Сообщений: 147
По умолчанию

помогать ещё нужно?
Ув. Форумчане! Если мои советы были Вам полезны, не забывайте благодарить в виде повышение рейтинга!!!
http://vkontakte.ru/id6715558
Arnezami вне форума Ответить с цитированием
Старый 18.05.2010, 03:32   #8
Casper-SC
Форумчанин
 
Регистрация: 04.07.2007
Сообщений: 549
По умолчанию

Цитата:
Сообщение от Arnezami Посмотреть сообщение
помогать ещё нужно?
Вроде бы всё уже получилось. Например я создаю форму сообщения в отдельном потоке, а в главном воспроизвожу музыку. При создании сообщения мне нужно передавать параметры, я просто делаю это через статические переменные, которые использую как указатели на главную форму например.
Код:
    public partial class FormSetting : Form
    {
        ......
        public static FormSetting frmSetting;
        public static AlarmClock AlClock;
        ......
    }
Код:
        private void CreateAlarm(int indexItem)
        {
            ConfigureMessageForm confMsgForm = new ConfigureMessageForm();
            //выводим сообщение в стиле указанном в будильнике
            AlarmClock ac = ((AlarmClock)this.listViewAlarm.Items[indexItem].Tag);
            frmSetting = this;
            AlClock = ac; //ссылаемся на будильник
            styleMsgForThr = ac.styleMessage;// нужно для thr

            Thread thr = new Thread(RunMessage);
            ......
            ......        
            thr.Start();
        }
Код:
        /// <summary>
        /// Запустить вывод сообщения на экран
        /// </summary>
        public  void RunMessage()
        {
            ShowMsg showMessage = new ShowMsg();
            switch (styleMsgForThr)
            {
                case StyleMessage.Stiker:
                    {
                        showMessage.Stiker(AlClock, frmSetting); //вот эти статические переменные
                    }
                    break;
                 ......
            }             
        }
Единственное не знаю правильный ли это подход?
Casper-SC вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
всплывающее окно(в отдельном потоке) Virus191288 Компоненты Delphi 8 21.01.2010 13:41
Загрузка данных в отдельном потоке Dj_smart Gamedev - cоздание игр: Unity, OpenGL, DirectX 8 18.01.2010 23:29
Закачка файла происходит в отдельном потоке. Kyran29 Работа с сетью в Delphi 1 28.11.2009 01:19
Проблема с созданием окна(CreateWindow) в отдельном потоке Sc0rp Win Api 4 26.03.2009 22:49
Запрос к БД в отдельном потоке (Thread) tyrell lab БД в Delphi 1 14.06.2007 08:42