Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось.
Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )
Здравствуйте, Mandigal, Вы писали:
M>У меня есть в проге длительная операция (рассчет CRC32 для файлов больше 1GB) и я хочу для нее создать отдельный рабочий поток
M>Делаю как в хелпах писано M>Глобальную управляющую функцию M>UINT MyThreadProc( LPVOID pParam ) M>{
M> CTestDlg::testThread(); M>return 0; M>} M>и ее вызов
M>void CTestDlg::OnBnClickedB1() M>{ M>AfxBeginThread(MyThreadProc,NULL); M>}
M>Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось. M>Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )
Вместо NULL передавай HWND диалога. А как закончишь расчет перешли результат через SendMessage.
Номер сообщения получай через RegiterWindowMessage
Удачи
CTestDlg::testThread() статическая?
Если нет, то твой код не скомпилируется.
Если да, то она не будет иметь доступ к нестатическим членам класса CTestDlg.
Мораль — делаем так:
Здравствуйте, BlackHeretic, Вы писали:
BH>Здравствуйте, Mandigal, Вы писали:
M>>У меня есть в проге длительная операция (рассчет CRC32 для файлов больше 1GB) и я хочу для нее создать отдельный рабочий поток
M>>Делаю как в хелпах писано M>>Глобальную управляющую функцию M>>UINT MyThreadProc( LPVOID pParam ) M>>{
M>> CTestDlg::testThread(); M>>return 0; M>>} M>>и ее вызов
M>>void CTestDlg::OnBnClickedB1() M>>{ M>>AfxBeginThread(MyThreadProc,NULL); M>>}
M>>Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось. M>>Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )
BH>Вместо NULL передавай HWND диалога. А как закончишь расчет перешли результат через SendMessage. BH>Номер сообщения получай через RegiterWindowMessage BH>Удачи
Хорошо, я передал HWND диалога с помощью GetSafeHwnd()
а дальше мне его как использовать?
и зачем мне передавать что-то через SendMessage если функция CTestDlg::testThread() и так сама в эдитбоксы значения записывает
Суть в том что в CTestDlg::testThread() находиться тот же код который раньше был в CTestDlg::OnBnClickedB1(), просто я хотел эту всю операцию отдельным потоком сделать
Здравствуйте, Vamp, Вы писали:
V>CTestDlg::testThread() статическая? V>Если нет, то твой код не скомпилируется. V>Если да, то она не будет иметь доступ к нестатическим членам класса CTestDlg. V>Мораль — делаем так:
V>
Здравствуйте, Mandigal, Вы писали:
M>Здравствуйте, BlackHeretic, Вы писали:
BH>>Здравствуйте, Mandigal, Вы писали:
M>>>У меня есть в проге длительная операция (рассчет CRC32 для файлов больше 1GB) и я хочу для нее создать отдельный рабочий поток
M>>>Делаю как в хелпах писано M>>>Глобальную управляющую функцию M>>>UINT MyThreadProc( LPVOID pParam ) M>>>{
M>>> CTestDlg::testThread(); M>>>return 0; M>>>} M>>>и ее вызов
M>>>void CTestDlg::OnBnClickedB1() M>>>{ M>>>AfxBeginThread(MyThreadProc,NULL); M>>>}
M>>>Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось. M>>>Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )
BH>>Вместо NULL передавай HWND диалога. А как закончишь расчет перешли результат через SendMessage. BH>>Номер сообщения получай через RegiterWindowMessage BH>>Удачи
M>Хорошо, я передал HWND диалога с помощью GetSafeHwnd() M>а дальше мне его как использовать? M>и зачем мне передавать что-то через SendMessage если функция CTestDlg::testThread() и так сама в эдитбоксы значения записывает M>Суть в том что в CTestDlg::testThread() находиться тот же код который раньше был в CTestDlg::OnBnClickedB1(), просто я хотел эту всю операцию отдельным потоком сделать
Вызывать методы из другого потока, особенно которые меняют что-то, небезопасно. Как минимум данные могут быть не корректны. А сообщение придет в рамках потока диалога и не с кем не законфликтует. Ловить это лучше в WindowProc диалога. Просто я тока вчера написал реализацию подобной байды — тока у меня нужно было по HTTP кое что скачивать. Все чудненько работает
Здравствуйте, BlackHeretic, Вы писали:
BH>Здравствуйте, Mandigal, Вы писали:
M>>Здравствуйте, BlackHeretic, Вы писали:
BH>>>Здравствуйте, Mandigal, Вы писали:
M>>>>У меня есть в проге длительная операция (рассчет CRC32 для файлов больше 1GB) и я хочу для нее создать отдельный рабочий поток
M>>>>Делаю как в хелпах писано M>>>>Глобальную управляющую функцию M>>>>UINT MyThreadProc( LPVOID pParam ) M>>>>{
M>>>> CTestDlg::testThread(); M>>>>return 0; M>>>>} M>>>>и ее вызов
M>>>>void CTestDlg::OnBnClickedB1() M>>>>{ M>>>>AfxBeginThread(MyThreadProc,NULL); M>>>>}
M>>>>Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось. M>>>>Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )
BH>>>Вместо NULL передавай HWND диалога. А как закончишь расчет перешли результат через SendMessage. BH>>>Номер сообщения получай через RegiterWindowMessage BH>>>Удачи
M>>Хорошо, я передал HWND диалога с помощью GetSafeHwnd() M>>а дальше мне его как использовать? M>>и зачем мне передавать что-то через SendMessage если функция CTestDlg::testThread() и так сама в эдитбоксы значения записывает M>>Суть в том что в CTestDlg::testThread() находиться тот же код который раньше был в CTestDlg::OnBnClickedB1(), просто я хотел эту всю операцию отдельным потоком сделать
BH>Вызывать методы из другого потока, особенно которые меняют что-то, небезопасно. Как минимум данные могут быть не корректны. А сообщение придет в рамках потока диалога и не с кем не законфликтует. Ловить это лучше в WindowProc диалога. Просто я тока вчера написал реализацию подобной байды — тока у меня нужно было по HTTP кое что скачивать. Все чудненько работает
Спасибо Vamp метод помог решить задачу, в моем приложении в этом потоке просто в эдит боксы добавляются значения CRC32 файлов так что по идее тут конфликтовать не чему (просто набросок проги пока, иначе кто бы стал в одной функции делать и рассчет CRC32 и вывод результатов в окно )
Но по идее вариант предложенный BlackHeretic должен быть конечно понадежнее, буду смотреть как его реализовывать, я же просто пока вообще всегда работал с одним потоком (необходимости не было)
Кстати BlackHeretic если есть вариант реализованный так как ты описал, то не мог бы ты мне его на мыло скинуть (скелет, просто кому кто и когда что передает), ну это я уже по собственной лени так как еще не смотрел что там вообще делать надо
Спасибо всем большое!
Здравствуйте, Mandigal, Вы писали:
M>Здравствуйте, BlackHeretic, Вы писали:
M>Спасибо Vamp метод помог решить задачу, в моем приложении в этом потоке просто в эдит боксы добавляются значения CRC32 файлов так что по идее тут конфликтовать не чему (просто набросок проги пока, иначе кто бы стал в одной функции делать и рассчет CRC32 и вывод результатов в окно ) M>Но по идее вариант предложенный BlackHeretic должен быть конечно понадежнее, буду смотреть как его реализовывать, я же просто пока вообще всегда работал с одним потоком (необходимости не было) M>Кстати BlackHeretic если есть вариант реализованный так как ты описал, то не мог бы ты мне его на мыло скинуть (скелет, просто кому кто и когда что передает), ну это я уже по собственной лени так как еще не смотрел что там вообще делать надо M>Спасибо всем большое!
Здравствуйте, Mandigal, Вы писали:
M>Кстати BlackHeretic если есть вариант реализованный так как ты описал, то не мог бы ты мне его на мыло скинуть (скелет, просто кому кто и когда что передает), ну это я уже по собственной лени так как еще не смотрел что там вообще делать надо
А собственно вот и код
Юзайте
BOOL CTPingerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Заскипано
m_message = RegisterWindowMessage(_T("SomeStringThatIWant"));
return TRUE; // return TRUE unless you set the focus to a control
}
void CTPingerDlg::OnBnClickedRun()
{
CPingThread* pPingThread = new CPingThread(m_hWnd, m_message, url, include, exclude);
pPingThread->CreateThread();
}
LRESULT CTPingerDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == m_message)
{
ProcessResultsOfThread(wParam);
delete (CPingThread*)lParam;
return 0;
}
return CDialog::WindowProc(message, wParam, lParam);
}
class CPingThread
{
HWND m_hWnd;
UINT m_message;
CString m_url;
CString m_incl;
CString m_excl;
public:
CPingThread(HWND hWnd, UINT message, const CString& url, const CString& incl, const CString& excl) : m_hWnd(hWnd), m_message(message),m_url(url), m_incl(incl), m_excl(excl) {}
static DWORD Run(CPingThread* pPT);
void CreateThread();
};
DWORD CPingThread::Run(CPingThread* pPT)
{
CHttpFileReader fr;
SendMessage(pPT->m_hWnd, pPT->m_message, (WPARAM)fr.IsAvailable(pPT->m_url, pPT->m_incl, pPT->m_excl), (LPARAM)pPT);
// Здесь можно было бы написать "delete pPT", только тогда не забыть компилить как многопоточное приложениеreturn 0;
}
void CPingThread::CreateThread()
{
DWORD id;
::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Run, this, 0, &id);
}