Newsgroup: it.comp.programmare.win32
Titolo: Worker thread con MFC

Ho creato una classe MFC che, al suo interno, ha bisogno di un worker thread
che viene avviato dal costruttore, e fermato dal distruttore (che, per
correttezza, non fa altro che segnalargli di fermarsi).
Il problema è che non riesco a specificare la funzione membro Worker() come
parametro della AfxBeginThread che si trova nel costruttore. Eppure Worker() è
definita come UINT Worker(LPVOID unused).
Sarà per via del puntatore this? Come faccio ad evitarlo?
--
Stefano Pettini
Risposte solo sul newsgroup, please.

 Sarà per via del puntatore this? Come faccio ad evitarlo?
Mi sembra di capire che tu abbia un errore in fase di compilazione, in
questo caso sarebbe stato utile che lo riportassi.
Parli di Worker come funzione membro, l'errore potrebbe essere proprio qui.
Se non sbaglio (e spero che in tal caso qualcuno mi corregga), la funzione
di controllo del Worker Thread non puo' essere membro di una classe, ma deve
essere una funzione dichiarata globalmente.
Jeremi

 definita come UINT Worker(LPVOID unused).
Deve essere una funzione statica.
Fausto


Il worker thread, se e' una funzione membro di una classe, deve essere
dichiarata statica. Altrimenti, deve essere una funzione globale
dichiarata al di fuori della classe. In ogni caso, non da' accesso la
puntatore this.
Poi, sempre se per la tua applicazione e' lo stesso, proverei ad
avviare il worker thread non all'interno del costruttore della classe,
bensi' nella InitInstance().
Ciao!
Massimo Fauro

 bensi' nella InitInstance().
Il worker thread non è unico per l'applicazione, ma è per ogni istanza della
mia classe (che non è una CWinApp). In poche parole mi serve un worker thread
diverso per ogni istanza. E che lavori sui membri di essa! Penso che passerò
"manualmente" il puntatore this come parametro LPVOID del worker.


Prova a vedere se questa soluzione ti puo' andare bene...
la ThreadCall() deve essere ridefinita in ogni classe che deriva dalla
MfxThread.
MM
---- header file ----
class MfxThread
{
public:
 virtual bool Close();
 virtual bool Open();
 bool IsRunning() { return _thread!=0; }
public:
 MfxThread();
 virtual ~MfxThread();
private:
 static DWORD WINAPI Run(MfxThread* amico);
  // funzione di esecuzione del thread
 virtual void ThreadCall() =0;
  // utilizzata dal thread
private:
 bool _closeThread;
  // flag per richiedere la chiusura del thread
 DWORD _thread_id;
  // identificativo del thread
 HANDLE _thread;
  // thread per la ricezione dei dati dalla macchina
};
---- header file ----
---- implementation file ----
#include "MfxThread.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
MfxThread::MfxThread()
: _thread(0), _closeThread(false)
{}
MfxThread::~MfxThread()
{
 ASSERT(_thread==0);
}
//////////////////////////////////////////////////////////////////////
//
bool MfxThread::Open()
{ 
 ASSERT(_thread==0);
 _thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Run, this, 0, &_thread_id);
 _closeThread = false;
 return true;
}
bool MfxThread::Close()
{
 ASSERT(_thread!=0);
 _closeThread = true;
 WaitForSingleObject(_thread, 5000);
 CloseHandle(_thread);
 _thread = 0;
 return true;
}
//////////////////////////////////////////////////////////////////////
//
DWORD WINAPI MfxThread::Run(MfxThread *amico)
{
 do {
  amico->ThreadCall();
 } while (amico->_closeThread==false);
 return 0;
}
---- implementation file ----

 "manualmente" il puntatore this come parametro LPVOID del worker.
Non capisco. Quello che pensavo io e' che tu avessi bisogno di un
worker thread del tipo
UINT MyThread (LPVOID pParam);
che venisse 'attivato' all'interno di una classe con la
AfxBeginThread(....). Se, in ogni istanza della tua classe attivi il
thread, hai tanti thread attivi quante sono le istanze (tutto si
svolge nello stack assegnato a ciascuna istanza della classe). Quindi
non sarebbe l'unico per l'applicazione. Oppure mi sfugge qualcosa?
Scusami, ma oggi ho il neurone sconnesso...
Massimo Fauro