Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Problem bei Thread (evtl ListCtrl schuld?)

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
29.01.2006, 22:07 Uhr
Tommyknocker1980



Hallo,

folgendes Problem :
Ich habe einen Thread, doch irgendwie scheint sich etwas zu verklemmen.


Beschreibung des Programms:
Mein Thread ändert zyklisch die Beschriftung der Zeileninhalte einer ListrCtrl (Diese hat insgesamt nur 4 Zeilen).

Problem:
Wenn ich wild an der Oberfläche herumklicke bleibt das Programm hängen!

Mit wild herumklicken meine ich zB: Schnelles öffnen/schließen eines Popup-Menüs (erscheint beim Klicken auf meine Toolbar) oder einfach mal lange Mausklicks auf die Oberfläche etc..

Hinweis
Mein Programm ist zwar für embedded Visual C++ (für PDA), aber vielleicht weiß ja jemand hier auch einen Rat.

FRAGE
Hängt das vielleicht mit dem schnellen umändern der Listenzeile mittels SetItemText zusammen? Manchmal erwischt man anscheinend einen Zeitpunkt wo sich das System "aufhängt". Vielleicht löst SetItemText intern irgendwelche MFC-Messages aus auf deren Antwort gewartet werden muss, und gleichzeitig werden auch Windows-Messages beim Öffnen des Popup-Menüs erzeugt, auf deren Abarbeitung gewartet werden muss (Liste wird ja über Thread upgedatet)

Code
Mein Thread ist eine statische private Methode meiner Klasse und wird wie folgt aufgerufen:


C++:
void CMyClass::StartThread(void)
{
  // Anweisungen ...

  AfxBeginThread(ThreadProc, this, THREAD_PRIORITY_NORMAL);

  // Anweisungen ...
}



Hier der Quellcode des Threads und der Methode zum Upaten der ListCtrl:



C++:
UINT CMyClass::ThreadProc(LPVOID pParam)
{
  CMyClass* pView = (CMyClass*) pParam;
  ASSERT(pClass);

  while(!pClass->m_bThreadStopped)
  {
    // Anweisungen ...
  
    // Aufruf einer Methode welche die ListCtrl von CMyClass updatet

    pClass->UpdateList();

    // Anweisungen ...
  }

  ExitThread(0);
  return 0;
}


void CMyClass::UpdateList(void)
{
   // Anweisungen ...

   // Aktuelle betrachteten Eintragder Liste updaten, also
   // den Beschriftungstext ändern
   // m_pMyList ist von ListCtrl abgeleitet

   m_pMyList->UpdateItem(m_nCurrentItem, strNewItemText)

   // Anweisungen ...
}




Hier der wichtige Code der von ListCtrl abgeleiteten Klasse

C++:
void CMyListCtrl::UpdateItem(int nItem, CString strItemText)
{
  // Neuen String auf dem Heap erzeugen. Weiß ja nicht wann die
  // Nachrichtenbehandlung erfolgt in welcher der String gebraucht wird.

  CString* pStrItemText= new CString(strItemText);

  // Die Nachricht WM_UPDATE_ITEM benutzerdefiniert
  // Nachricht versenden, damit das ausführen des Listupdates im
  // "Hauptthread" stattfindet

  PostMessage(WM_UPDATE_ITEM, (WPARAM) nItem, (LPARAM) pStrItemText);
}


LRESULT CMyListCtrl::OnUpdateItem(WPARAM wParam, LPARAM lParam)
{
  int nIndex = (int) wParam;
  CString *pStrItemText= (CString *) lParam;

  SetItemText(nIndex , 0, *pStrItemText);

  // Speicher auf dem Heap wieder frei geben

  delete pStrItemText;

  return 0L;
}



Durch das Senden der Nachricht WM_UPDATE_ITEM wird der Update der Liste im "Hauptthread", welcher "Besitzer" der Oberflöche ist, durchgeführt.

Weiß keinen Rat warum mein Programm hängen bleibt und bin für jede Bemerkung/Hilfe dankbar!

Vielen Dank,
Gruß Tom

Dieser Post wurde am 29.01.2006 um 22:07 Uhr von Tommyknocker1980 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
31.01.2006, 05:54 Uhr
Spacelord
Hoffnungsloser Fall


Hallo,
ich würde an deiner Stelle mal probieren den Methodenaufruf aus dem Thread

C++:
pClass->UpdateList();


durch nen Aufruf der globalen Funktion ::PostMessage zu ersetzen.
Letztendlich ist der Zugriff auf das Dialogobjekt nicht synchronisiert.
Eventuell noch ne benutzerdefinierte Nachricht anlegen und diese dann an den Dialog senden.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
31.01.2006, 09:38 Uhr
(un)wissender
Niveauwart


Jupp, daran liegt es. GUI-Aufrufe dürfen nur aus dem Hauptthread gemacht werden. Hatte das Problem auch schon mal unter C# im .NET Compact Framework 1.1
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
31.01.2006, 13:04 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



Zitat:

GUI-Aufrufe dürfen nur aus dem Hauptthread gemacht werde


Das problem kann man aber imho mit PostMessage versuchen zu umschiffen...


Bearbeitung:

argh... ich sollte lernen nicht nur die beiträge von (un)wissender zu lesen. Hab glatt den von Spacy zu schnell überflogen...


--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 31.01.2006 um 13:05 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
31.01.2006, 13:50 Uhr
~Tommyknocker1980
Gast


Die Methode CMyListCtrl::UpdateItem sendet doch bereits ein PostMessage, damit in CMyListCtrl::OnUpdateItem der Update im Hauptthread abläuft.



In der Methode CMyClass::UpdateListhabe ich den Aufruf auch mal wie folgt geändert:


Code:

CSingleLock sLock(&(theApp.m_criticalSection));
sLock.Lock();

m_pMyList->UpdateItem(m_nCurrentItem, strNewItemText)

sLock.Unlock();




Auch das schafft keine Abhilfe. Vielleicht könntet Ihr mir ein paar ausführlichere Erläuterungen geben?

Soweit habe ich verstanden, dass aus einem Thread kein Oberflächenupdate stattfinden darf. Dies wollte ich umgehen, siehe erstes Post.

Komme aber auf keinen grünen Zweig.

Danke
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
31.01.2006, 16:26 Uhr
(un)wissender
Niveauwart


@Winfalf
Ich will da mal großzügig sein. Meine Beiträge ist meistens auch die wesentlichen.

@~Tommyknocker1980
Das hilft überhaupt nicht, im Gegenteil. Genau so etwas verursacht das Lock, da alle MessageHandler synchronisiert sind.

Nimm mal, wie Spacelord gesagt hat das globale ::PostMessage. Vielleicht hilft es. Ansonsten muss es noch andere Stellen geben, in denen sich der Arbeitsthread und der Hauptthread in die Quere kommen.
--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 31.01.2006 um 16:26 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: