Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Вернуть управление вызывающему потоку  (Прочитано 4023 раз)
0 Пользователей и 1 Гость смотрят эту тему.
yudjin
Помогающий

ua
Offline Offline
Пол: Мужской

« : 25-08-2011 15:36 » 

Распараллелил функцию в главном потоке (средствами Rx Framework, но это значения не имеет, пробовал и через BeginInvoke()):
Цитата
public void Start()
        {
            //...
            var startSession = Observable.ToAsync<string, string>(this.StartSession);
            startSession(credentionals.Login, credentionals.Password);
            //...
        }

Она вызывает асинхронно долгоиграющий метод, который в конце должен кинуть эвент всем, кто его слушает:
Цитата
private void StartSession(string login, string password)
        {
            //...
            this.OnStarted(EventArgs.Empty);
        }

Встал вопрос - как сделать так, чтоб метод this.OnStarted() вызывался в главном потоке? Не могу понять, возможно ли это вообще.
Знаю, что обратная сторона Fork'а - Join, но при его помощи не выходит "слить" потоки обратно.

Из многопоточности пока только освоил разделение, lock'и и ManualResetEvent's  Улыбаюсь

PS: дело в том, что подписчики на событие Started - в основном GUI-компоненты, и они вредничают, если менять их не из главного потока. Переделывать UI на безопасные BeginInvoke() - много мороки, много кода уже написано.
Еще раз пересмотрел все темы про потоки - ничего подобного там нет... Я так понял, это связано больше с параллелизмом, но ведь даже за всеми фреймворками по паралеллизму стоят рядовые инструменты, значит это можно сделать стандартными средствами.


« Последнее редактирование: 25-08-2011 17:04 от yudjin » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 25-08-2011 18:14 » 

yudjin, вызвать метод в "другом" уже работающем потоке не так-то просто. Но принцип сводится к тому, что тот поток должен либо ждать события, либо периодически проверять наступление события и при наличии события вызывать метод OnStarted. По-другому - никак.

Если "другой" поток - это GUI, то разумно рассмотреть возможность посылки сообщения с помощью WinAPI в очередь приложения и обработки обычным образом.
« Последнее редактирование: 25-08-2011 18:16 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
yudjin
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #2 : 28-09-2011 15:50 » 

Просто для завершения картины выложу выбранное решение.

Отсоединяем поток:
Код:
public void Start()
        {

            //...
            this.synchronizationContext = SynchronizationContext.Current ?? new SynchronizationContext();
            var startSession = Observable.ToAsync<string, string>(this.StartSession);
            startSession(credentionals.Login, credentionals.Password);                               
            //...
        }


Посылаем сообщение вызывающему потоку и оттуда уже дергаем нужный метод
Код:
private void StartSession(string login, string password)
        {
            //...
            this.synchronizationContext.Post(state => this.OnStarted(EventArgs.Empty), null);   
        }

Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines