Проблемы с многопоточностью
От: Tyoma Developer Россия  
Дата: 21.09.07 10:48
Оценка:
Даже не знаю как описать проблему. Расскажу лучше что делаю:
Есть оконное приложение (С#), в котором создаётся вторичный поток. В этом потоке происходит вызов MessageBox.Show(...).

Задача:
Необходимо чтобы родителем этого диалогого окна (MessageBox-а) был объект главного класса Form, который естственно находится в другом потоке

Заранее благодарен

25.09.07 08:08: Перенесено модератором из '.NET' — TK
Temet nosce
Re: Проблемы с многопоточностью
От: Mab Россия http://shade.msu.ru/~mab
Дата: 21.09.07 10:51
Оценка: +2
Здравствуйте, Tyoma Developer, Вы писали:

Читайте про Control.Invoke/Control.BeginInvoke (а также о BackgroundWorker для общего развития). Но вообще сама необходимость показывать модальный диалог из worker thread скорее всего говорит о неверном проектировании.
Re[2]: Проблемы с многопоточностью
От: Аноним  
Дата: 21.09.07 13:34
Оценка:
Здравствуйте, Mab, Вы писали:

Mab>Здравствуйте, Tyoma Developer, Вы писали:


Mab>Читайте про Control.Invoke/Control.BeginInvoke (а также о BackgroundWorker для общего развития). Но вообще сама необходимость показывать модальный диалог из worker thread скорее всего говорит о неверном проектировании.


Я не автор топика, но возникает вопрос — а как отображать исключения, возникшие в параллельных потоках ?
Re[3]: Проблемы с многопоточностью
От: _FRED_ Черногория
Дата: 21.09.07 13:55
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>…а как отображать исключения, возникшие в параллельных потоках ?


Mab>Читайте про Control.Invoke/Control.BeginInvoke (а также о BackgroundWorker для общего развития).

... << RSDN@Home 1.2.0 alpha rev. 717>>
Help will always be given at Hogwarts to those who ask for it.
Re[4]: Проблемы с многопоточностью
От: _Morpheus_  
Дата: 21.09.07 15:07
Оценка:
Здравствуйте, _FRED_, Вы писали:

А>>…а как отображать исключения, возникшие в параллельных потоках ?


_FR>

Mab>Читайте про Control.Invoke/Control.BeginInvoke (а также о BackgroundWorker для общего развития).


зачем усложнять, если потоку так нужны свои диалоги — без проблем, для этого нужно запустить в этом потоке свой message pumping цикл и не нужно никаких инвоуков...

Другое дело если потоку нужно изменить форму или контрол, которые были создана в чужом потоке... Тогда конечно invoke...
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[5]: Проблемы с многопоточностью
От: _FRED_ Черногория
Дата: 21.09.07 15:22
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

_M_>зачем усложнять, если потоку так нужны свои диалоги — без проблем, для этого нужно запустить в этом потоке свой message pumping цикл и не нужно никаких инвоуков...


Я не считаю это достойным workaround-ом
... << RSDN@Home 1.2.0 alpha rev. 717>>
Help will always be given at Hogwarts to those who ask for it.
Re[6]: Проблемы с многопоточностью
От: _Morpheus_  
Дата: 21.09.07 16:00
Оценка:
Здравствуйте, _FRED_, Вы писали:

_M_>>зачем усложнять, если потоку так нужны свои диалоги — без проблем, для этого нужно запустить в этом потоке свой message pumping цикл и не нужно никаких инвоуков...


_FR>Я не считаю это достойным workaround-ом


почему? Может диалог потока должен жить полностью самостоятельной жизнью, а число обращений к нему этого потока может быть очень высоко, и что теперь, нагружать основной поток приложения дополнительной работой внушительного размера, нагружать код Invoke'ами? Учитывая что потоку глубоко наплевать на формы основного потока, он к ним не обращается, а обращается лишь к своему диалогу, который основному потоку тоже по барабану — это будет вполне логичное решение. Т.к. по сути мы запускаем еще один оконный процесс внутри тогоже процесса, мы можем избавиться от межпроцессного взаимодействия и увеличить скорость.
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[7]: Проблемы с многопоточностью
От: _Morpheus_  
Дата: 21.09.07 16:02
Оценка:
другое дело что задачи такие редко встречаются...
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[5]: Проблемы с многопоточностью
От: zloy_critic  
Дата: 23.09.07 10:04
Оценка: :)
Здравствуйте, УВАЖАЕМЫЙ _Morpheus_, Вы писали:

_M_>Здравствуйте, _FRED_, Вы писали:


А>>>…а как отображать исключения, возникшие в параллельных потоках ?


_FR>>

Mab>Читайте про Control.Invoke/Control.BeginInvoke (а также о BackgroundWorker для общего развития).


_M_>зачем усложнять, если потоку так нужны свои диалоги — без проблем, для этого нужно запустить в этом потоке свой message pumping цикл и не нужно никаких инвоуков...


_M_>Другое дело если потоку нужно изменить форму или контрол, которые были создана в чужом потоке... Тогда конечно invoke...


А не могли бы Вы кинуть ссылку на источник, как запустить "message pumping цикл"? Если уж самому трудно код написать. Зачем это bla-bla-bla? Я новичок, пришел на форум чему-то научиться, а тут все — или нагугл посылают, или в msdn... Какая тогда ценность форума rsdn? Пообщаться с двумя-тремя старыми соратниками, понимающими Вас с полуслова? (да и то, только потому, что несколько лет назад Вы сами также мучались и кто-то Вас научил, не пустоловными разглагольствованиями, а кодом, да еще, может, Ваш код фиксал) Общайтесь в аське, не позорьте форум, не превращайте его в то, во что украинские политики превратили Украину (я как раз там сейчас).
Да, может быть, "западло" (эмоции уже берут верх в моих рассуждениях) отвечать одно и то же из года в год, кидать давно надоевшие всем ссылки, но что делать, если в этом году в программирование приходят новые десятки тысяч человек, а толковых книг Вы и Ваши умудренные "ректальными отношениями" коллеги все не пишете и не пишете? А что Вы будете отвечать новичкам в следующем году? Через 5 лет?
Надоело заниматься копипастом своих старых ответов? Займитесь изучением новых технологий, другим видом жизнедеятельности, в конце-концов. Пусть ответят те, кто ХОЧЕТ ПОМОЧЬ. Никто не ответит? Да, потому что боятся получить в ответ на свой пост оскорбительные фразы, подкрепленные "улыбками" и "плюсами".
Я не только лично Вас критикую. Я посмотрел, многие участники занимают позиции часто деструктивные по отношению к автору топика. Автор уже и не участвует в обсуждении, он не интересен никому, все забыли про него.

Это критика, хорошая, или плохая — какая есть. Форум msdn собрал самых знающих, самых толковых, самых компетентных. И чем они занимаются? Какую миссию выполняют? На что тратят свое время?
"Может диалог потока должен жить полностью самостоятельной жизнью, а число обращений к нему этого потока может быть очень высоко, и что теперь, нагружать основной поток приложения дополнительной работой внушительного размера, нагружать код Invoke'ами? Учитывая что потоку глубоко наплевать на формы основного потока, он к ним не обращается, а обращается лишь к своему диалогу, который основному потоку тоже по барабану — это будет вполне логичное решение."
Что это? Зачем это?
Re[6]: Проблемы с многопоточностью
От: Tyoma Developer Россия  
Дата: 24.09.07 04:43
Оценка:
Не думал, что мой вопрос вызовет такое бурное обсуждение. Но всё же, не понимаю почему некоторые считают, что использование диалоговых окон в потоках, это признак неверного проектирования. Могу просто кратко обрисовать задачу:

Есть некоторое приложение у которого есть функция автоматического update-а (скачивание новой версии). Когда приложение запускается, оно проверяет наличие новой версии в нэте и если таковое обнаруживается, то появляется MessageBox с вопросом: "Не хотите ли обновить". Так вот эту проверку с диалогом я хочу запустить в отдельном потоке, т.к. не всегда эта проверка проходит быстро, а я не хочу чтобы она тормозила работу приложения

Буду рад если кто-нить подскажет иной путь решения этой проблемы. Насчёт Invoke, я его и юзаю, но вы просто наверно не представляете проблемы


public static void CheckForUpdate(bool ShowMessage) {
  ...
  // Вот тут мне нужно получить ссылку на главную форму, но т.к. этот метод запушен в другом потоке....
  // Может я зря это делаю, но пока не нашёл другого решения
  if (MessageBox.Show(!!!Pointer HERE!!!, "New version of " + System.Windows.Forms.Application.ProductName + " is available" +
                                      "\r\n Do you want to download and update it?",
                                      "New version is available",
              MessageBoxButtons.YesNo,
              MessageBoxIcon.Question) == DialogResult.Yes) {
  ...
  }
}

// вот что-то типа такого я делаю ---------------------------------------
private void FormMain_Load(object sender, EventArgs e) {
  m_CheckForUpdateThread = new Thread(new ThreadStart(CheckForUpdate));
  m_CheckForUpdateThread.Start();
}

public void GetFormMainPtr(ref FormMain FormMainPtr) {
  if (this.InvokeRequired) {
    GetFormMainPtrCallback callback = new GetFormMainPtrCallback(GetFormMainPtr);
    this.Invoke(callback, new object[] {FormMainPtr});
  }
  else {
    FormMainPtr = this;
  }
}
//Но это естественно не работает -----------------------------------------


Автору предыдущего ответа
Я конешно понимаю вас но хочу сказать, что иногда лучше самому в чём-то покапаться, чём требовать сразу готовенькое. Так ничему не научишся.
Temet nosce
Re[7]: Проблемы с многопоточностью
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 24.09.07 06:04
Оценка:
Здравствуйте, Tyoma Developer, Вы писали:

Попробуй внести код мессадж бокса в метод, для которого вызывается Invoke
Re[8]: Проблемы с многопоточностью
От: Tyoma Developer Россия  
Дата: 24.09.07 06:56
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Tyoma Developer, Вы писали:


G>Попробуй внести код мессадж бокса в метод, для которого вызывается Invoke


Проблема в том, что мне на данном этапе необходимо получить ссылку на объект главной формы, который был создан в другом потоке и не важно где будет располагаться код.
Temet nosce
Re[7]: Проблемы с многопоточностью
От: _FRED_ Черногория
Дата: 24.09.07 07:06
Оценка: 1 (1) +1
Здравствуйте, Tyoma Developer, Вы писали:

TD>Есть некоторое приложение у которого есть функция автоматического update-а (скачивание новой версии). Когда приложение запускается, оно проверяет наличие новой версии в нэте и если таковое обнаруживается, то появляется MessageBox с вопросом: "Не хотите ли обновить". Так вот эту проверку с диалогом я хочу запустить в отдельном потоке, т.к. не всегда эта проверка проходит быстро, а я не хочу чтобы она тормозила работу приложения


Расуждаешь ты верно, но выводы делаешь ошибочные. Проверка долгая? Сделай её в отдельном потоке. Потом, если обновления появились, сообщи в главный поток об их наличии и заверши поток. Главный поток должен будет спросить пользователя, не нужны ли ему обновления. Если нужны, то запускается ещё один служебный поток для загрузки обновлений и опять, когда все обновления загружены, надо спросить главный поток: готовы ставить? И начать установку.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Проблемы с многопоточностью
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.09.07 07:09
Оценка: 3 (1)
Здравствуйте, Tyoma Developer, Вы писали:
TD>Буду рад если кто-нить подскажет иной путь решения этой проблемы. Насчёт Invoke, я его и юзаю, но вы просто наверно не представляете проблемы
Наверное ты просто не понимаешь, что такое Invoke.
public static void CheckForUpdate(bool ShowMessage) {
  ...
  // Вот тут тебе не нужно получить ссылку на главную форму, т.к. этот метод запушен в другом потоке. Надо запустить мессаджбокс в нужном потоке:
    if(AskUserForDownload())
    {
  ...
  }
}

// вот что-то типа такого я делаю ---------------------------------------
private void FormMain_Load(object sender, EventArgs e) {
  m_CheckForUpdateThread = new Thread(new ThreadStart(CheckForUpdate));
  m_CheckForUpdateThread.Start();
}

private bool AskUserForDownload()
{
  if (InvokeRequired)
    {
      return (bool) Invoke(AskUserForDownload);
    }
    else
      return MessageBox.Show(this, string.Format(
@"New version of {0} is available
Do you want to download and update it?")
,"New version is available",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question) == DialogResult.Yes;
}

//это естественно cработает -----------------------------------------
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Проблемы с многопоточностью
От: Tyoma Developer Россия  
Дата: 24.09.07 08:21
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Tyoma Developer, Вы писали:

TD>>Буду рад если кто-нить подскажет иной путь решения этой проблемы. Насчёт Invoke, я его и юзаю, но вы просто наверно не представляете проблемы
S>Наверное ты просто не понимаешь, что такое Invoke.
S>
S>public static void CheckForUpdate(bool ShowMessage) {
S>  ...
S>  // Вот тут тебе не нужно получить ссылку на главную форму, т.к. этот метод запушен в другом потоке. Надо запустить мессаджбокс в нужном потоке:
S>    if(AskUserForDownload())
S>    {
S>  ...
S>  }
S>}

S>// вот что-то типа такого я делаю ---------------------------------------
S>private void FormMain_Load(object sender, EventArgs e) {
S>  m_CheckForUpdateThread = new Thread(new ThreadStart(CheckForUpdate));
S>  m_CheckForUpdateThread.Start();
S>}

S>private bool AskUserForDownload()
S>{
S>  if (InvokeRequired)
S>    {
S>      return (bool) Invoke(AskUserForDownload);
S>    }
S>    else
S>      return MessageBox.Show(this, string.Format(
S>@"New version of {0} is available
S>Do you want to download and update it?")
S>,"New version is available",
S>                MessageBoxButtons.YesNo,
S>                MessageBoxIcon.Question) == DialogResult.Yes;
S>}

S>//это естественно cработает -----------------------------------------
S>


Спасибо Агромное. Да, действительно я не понимаю что такое Invoke, я ещё не совсем разбираюсь в принципах построения многопоточных приложений.
Temet nosce
Re[9]: Проблемы с многопоточностью
От: _Morpheus_  
Дата: 25.09.07 11:31
Оценка:
Здравствуйте, Tyoma Developer, Вы писали:

G>>Попробуй внести код мессадж бокса в метод, для которого вызывается Invoke


TD>Проблема в том, что мне на данном этапе необходимо получить ссылку на объект главной формы, который был создан в другом потоке и не важно где будет располагаться код.


и кто вас учит статики кругом пихать?


private void formMainCheckUpdateProc(bool ShowMessage) 
{
  //...

    if(this.InvokeRequired)
        Invoke(updateRequest, null);
    else
        updateRequest();

    //...
}

private void updateRequired()
{
    // Вот тут мне нужно получить ссылку на главную форму, но т.к. этот метод запушен в другом потоке....
  // Может я зря это делаю, но пока не нашёл другого решения

    
        // без проблем - получай, this - это ссылка на главную форму...
        // более того, этот код будет выполняться из основного потока приложения (того в котором форма создана)


  if (MessageBox.Show(this, "New version of " + System.Windows.Forms.Application.ProductName + " is available" +
                                      "\r\n Do you want to download and update it?",
                                      "New version is available",
              MessageBoxButtons.YesNo,
              MessageBoxIcon.Question) == DialogResult.Yes) {
  //...
  }
}

// вот что-то типа такого я делаю ---------------------------------------
private void FormMain_Load(object sender, EventArgs e) 
{
  m_CheckForUpdateThread = new Thread(new ThreadStart(formMainCheckUpdateProc));
    m_CheckForUpdateThread.IsBackground = true;
  m_CheckForUpdateThread.Start();
}
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[10]: Проблемы с многопоточностью
От: _FRED_ Черногория
Дата: 25.09.07 11:46
Оценка:
Здравствуйте, _Morpheus_, Вы писали:

_M_>и кто вас учит статики кругом пихать?


Какие "статики"? Статические методы? Чем же они плохи?
Help will always be given at Hogwarts to those who ask for it.
Re[11]: Проблемы с многопоточностью
От: _Morpheus_  
Дата: 25.09.07 11:58
Оценка:
Здравствуйте, _FRED_, Вы писали:

_M_>>и кто вас учит статики кругом пихать?


_FR>Какие "статики"? Статические методы? Чем же они плохи?


человек прикрутил статический метод, а теперь думает как из него получить экземпляр объекта... както даже не смешно
... << RSDN@Home 1.2.0 alpha rev. 676>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.