Каков шаблон для выполнения задачи с потоком и последующего действия? - PullRequest
2 голосов
/ 03 марта 2012

Что я делаю:

  • Есть приложение с плеером
  • Пользователь нажимает кнопку «Воспроизвести», «Загрузить файл» или «Воспроизвести и загрузить файл»
  • Запускает поток для загрузки файла.

Я разрабатываю с C ++ с MFC, и поток не может легко получить доступ к внутренним компонентам Я могу просто передать HI / LOWWORD.

Когда поток заканчивается и возвращается к основному потоку, как я могу сообщить, какое действие должен выполнить поток? На самом деле я передаю в конструкции потока действие, например:

Вызов: StartThread(file, PLAY);

Конец нити: pClass->SendMessage(WM_DOWNLOADVIDEOTHREADEND,(WPARAM)downloadedfile,ACTION);

И затем, когда приложение получает сообщение DOWNLOADVIDEOTHREADEND , оно проверяет ДЕЙСТВИЕ и делает это.

Но это не выглядит элегантно, это беспорядок!

Есть какой-то шаблон для этого?

Есть лучший способ сделать это?

Ответы [ 2 ]

1 голос
/ 03 марта 2012

По моему мнению, вы должны разделить часть пользовательского интерфейса вашего приложения с вашей логической частью в разных модулях. Допустим, вы написали модуль с именем player, вам нужно предоставить интерфейс для слушателя плеера, например, свинг Java, сделайте это для кнопок. После этого вы можете отслеживать ваши события везде, независимо от используемой вами технологии (QT, MFC, VCL и т. Д.). Таким образом, вы можете реализовать мост, стратегию или шаблон наблюдателя в этом случае. Я приведу пример с шаблоном проектирования моста:

class Player{
private:
  IPlayerListener* _listener;

private:
  static void threadCallback( void* arg ){
     Player* player = (Player*)arg;
     //Download file here
     player._listener->downloadComplete( track );
  }

public:
  Player( IPlayerListener* listener ){
    _listener = listener;
  }

  bool playFile( uri file ){
    //Start a new thread and do all staff needed to download the file in there.
    thread.start(threadCallback, this);
  }
};

В вашем интерфейсе объявляются все типы событий, которые игрок может бросить:

class IPlayerListener{
public:
 //...
 virtual void downloadComplete( const string& track )=0;
 //...
};

Избегайте использования библиотек, таких как MFC, в вашем проекте, потому что это может вызвать некоторые проблемы в будущее. Вы можете перейти на другую платформу или принять решение использовать другую библиотеку, например QT, для своего графического интерфейса.

Удачи.

0 голосов
/ 03 марта 2012

Очень часто основной поток в приложении тратит большую часть своего времени в ожидании событий, происходящих с WaitForMultipleObjects (), а затем делает что-то, когда это происходит с уведомлением о том, что событие произошло.

Если вы обрабатываете результат CreateThread () как еще одну вещь, которую нужно ждать в WaitForMultipleObjects (), он будет отображаться как событие, когда поток завершается, поэтому вы можете рассматривать это событие так же, как и любое другое - см., Например, http://msdn.microsoft.com/en-us/library/windows/desktop/ms682516%28v=vs.85%29.aspx.

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

Если вы сыты по горло MFC и знаете о лучшем дизайне интерфейса, у вас есть возможность написать оболочку в MFC и представить этот дизайн интерфейса или что-то в этом роде остальной части программы.

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