Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Запустить метод в другом потоке


Автор: CYBERDREAM 31.1.2008, 12:40
Доброго времени суток всем.
Есть главный поток приложения - <<MAIN>>. И несколько второстепенных. 
Мне нужно из второстепенного потока, запустить метод в главном. Каким образом можно это осуществить?

Автор: farad 31.1.2008, 13:39
выстави флаг из второстепенного потока в виде какой-нибудь статической открытой переменной, а в главном ее проверяй..

Добавлено через 2 минуты и 37 секунд
PostMessage можно еще через API делать

Автор: CYBERDREAM 31.1.2008, 14:41
Вопрос, как в главном потоке осуществлят проверку? Таймером?

Автор: farad 31.1.2008, 15:10
Цитата(CYBERDREAM @  31.1.2008,  14:41 Найти цитируемый пост)
как в главном потоке осуществлят проверку?
если поток ничего не делает, то таймером. Если в нем выполняется какая-то работа - то в процессе вычислений делать проверку флага.. Если не хочется связываться с таймером шли главному окну сообщения через PostMessage, когда дойдет очередь до твоего сообщения - оно будет обработано.. ну ловить его естественно в WndProc...

Добавлено через 2 минуты и 24 секунды
Да. еще не стоит использовать SendMessage - есть риск наглухо залочить все твои потоки

Автор: KLUBS 31.1.2008, 17:40
а не проще 




{
Invoke(...)
}

Автор: farad 31.1.2008, 18:52
Цитата(KLUBS @  31.1.2008,  17:40 Найти цитируемый пост)
а не проще {Invoke(...)}
ну если есть главная форма в главном потоке, тогда скорее всего проще.. Но это должно быть обращение к контролам, а если нам надо просто метод дернуть, ну тогда хз. Я бы тогда тупо через флаги делал.. 

Автор: KLUBS 31.1.2008, 19:01
зачем контролы??????????? this.Invoke.......

Автор: farad 31.1.2008, 19:34
Цитата(KLUBS @  31.1.2008,  19:01 Найти цитируемый пост)
зачем контролы??????????? this.Invoke
А Invoke(...)разве не метод класса Control?

Автор: CYBERDREAM 1.2.2008, 09:59
Сдаетс мне, farad прав, тогда остается лишь вариант с таймером, хотя и не очень желаемый smile 

Автор: KLUBS 1.2.2008, 18:09
хм.. а разве необходимо приложение не содрежащие ни одного контрола?? какое если не секрет???
можно создать класс 

Код


A : Control

A a = new A();

A.Invoke()....

Автор: Alexsar 2.2.2008, 00:21
Зачем вообще так делать? IMHO всё можно решить с помощью делегатов
вот к примеру код

//объявляется в неймспейсе проекта
delegate void SetTextCallback(string text, Control e);

......

//метод класса
 private void SetText(String text, Control e)
        {
            if (/*this.*/e.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text, e });
            }
            else
            {
                e.Text = text;
            }
        }
........
//метод второстепенного потока
while(true)
        {
            SetText(sek.ToString(), this.textbox1);
            sek++;
            Thread.Sleep(1000);
         }

Данный пример иллюстрирует один из способов решения проблемы, этот код можно использовать например для формы, в которой есть текстовое поле-секундомер(контрол - в главном потоке, а данные формируются во второстепенном). Так как контрол живёт в главном потоке, а свойства его можно изменять только поток породивший его, то если просто в другом потоке тупо набрать textbox1.Text = "бла бла"; ничего хорошего не будет. А используя делегаты всё чётко, один поток отвечает за прорисовку контролов, другой изменяет данные, вызывая нужную функцию. Делегаты rulezzzzzz smile 

Автор: CYBERDREAM 2.2.2008, 00:37
Thx Alexsar, предполагал что делегаты дадут верный ответ, но с ними еще не подружился, постараюсь завтра сделать шаг им навстречу.

Автор: KLUBS 2.2.2008, 01:11
даа))
я такого не знал, спасибо))

Автор: farad 2.2.2008, 20:38
Цитата(Alexsar @  2.2.2008,  00:21 Найти цитируемый пост)
Зачем вообще так делать? IMHO всё можно решить с помощью делегатов

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

Добавлено через 1 минуту и 29 секунд
Alexsar, а Invoke связано с контролами, о чем говорили в самом начале..

Автор: Alexsar 2.2.2008, 23:58
ну тогда если не устраивают делегаты используй события класса AutoResetEvent.
второстепенный поток будет генерировать событие - Set, а главный ждать с помощью WaitOne, так уж точно будет выполнять всё главный поток, и без всяких таймеров и флагов

Автор: CYBERDREAM 13.2.2008, 11:54
Как писалось выше - Делегаты рулят. Помогли избавиться от таймеров, флагов и вытекающих проблем.
Код

        delegate void del();
        del deleg;
        ....
        void ThreadMethod()
        {
            //Метод второстепенного потока
            .....
            this.Invoke(deleg);
        }
        void StartTimer()
        {
            //Выполнени в основном потоке
        }

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)