[C#] Window.show() werkt niet bij callback

Pagina: 1
Acties:

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Dit is de situatie. Ik start een connectie. Na verbinding gemaakt te hebben begin ik met Socket.BeginReceive() een a-synchrone ontvangst van gegevens. Wanneer deze gegevens binnenkomen wordt een callback aangeroepen die de binnenkomende berichten verwerkt.

Dit werkt allemaal goed. Aan de hand van het inkomende bericht wordt vervolgens een event aangeroepen naar de client programmeur.

Alleen nu wil ik in die event een window laten zien en dit werkt niet :(
Ik doe
code:
1
2
ConversationWindow window = new ConversationWindow();
window.Show();

Dit zou voldoende moeten zijn en dat is het ook wanneer ik deze gewoon onder een knop plaats op mijn mainwindow.

Alleen wanneer ik deze code gebruik in een event-afhandeling (dus in feite in een aparte thread) dan bevriest het nieuwe scherm. De rest van het programma loopt wel door.
De controls in het nieuwe wenster worden dus niet meer gepaint en niks reageert meer in dit venster.

Hoe kan ik dit oplossen? :)

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Als ik
window.ShowModal();
doe dan werkt het wel. Maar dan krijg ik dus geen binnenkomende berichten meer, immers de thread die de event aanroept handelt ook de berichten af.

Oftewel ik moet op 1 of andere manier die window maken/laten zien via de 'hoofd' thread.

Verwijderd

Dus het scherm verschijnt wel, maar refresht niet? En het handmatig aanroepen van window.Refresh() en/of window.ResumeLayout() helpen ook niet?

Kan je anders niet een (static) methode aanmaken in je hoofdthread waarin je code staat om een form te showen?

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 19 juli 2002 18:28 schreef KoenM het volgende:
Dus het scherm verschijnt wel, maar refresht niet? En het handmatig aanroepen van window.Refresh() en/of window.ResumeLayout() helpen ook niet?

Kan je anders niet een (static) methode aanmaken in je hoofdthread waarin je code staat om een form te showen?
Met Refresh en ResumeLayout zie je wel iets meer. Maar dat is gewoon brute oplossing want hierna loopt het venster alsnog vast.
De static functie helpt ook niet.

Het venster krijgt dus geen windowsmessages meer door om te processen. Dit is (denk ik) logisch aangezien de thread waarin die gestart wordt gaat slapen en pas weer actief wordt zodra er nieuwe data binnenkomt op de socket.

Ik zou dus misschien een aparte thread kunnen maken voor elke keer dat ik zo'n window maak, maar dat vind ik ook lelijk. Immers je kan gemakkelijk meerdere windows in 1 thread bewaken.

Verwijderd

Application.DoEvents();
aanroepen na het wegschrijven van data naar je scherm.

Als jullie mij ook niet hadden ;)

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Op vrijdag 19 juli 2002 20:30 schreef Otis het volgende:
Application.DoEvents();
aanroepen na het wegschrijven van data naar je scherm.
Ik heb deze aanroep gedaan direct na de Show() method, maar dit helpt ook niet...

Ik zal eens een wat simpelere opstelling met hetzelfde concept maken misschien dat de fout toch ergens anders ligt.

Of misschien dat ik een nieuwe thread moet maken en in die nieuwe thread het venster starten en vervolgens direct de thread eindigen?

Verwijderd

Op zaterdag 20 juli 2002 13:33 schreef Orphix het volgende:

[..]

Ik heb deze aanroep gedaan direct na de Show() method, maar dit helpt ook niet...
huh? Dan is er iets anders aan de hand (i.e.: je routine die naar het scherm moet schrijven wordt nooit aangeroepen). DoEvents() handelt alle windows messages af die gepost zijn.

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Het is opgelost! :)
Ja het probleem lag er dus in dat ik het venster maakte in een andere thread dan waar ik bijvoorbeeld mijn main form in creeer. Deze thread gaat elke keer slapen zodra er geen data meer beschikbaar is. Niet geschikt dus voor message-pumping voor je windows.

De oplossing was om een methode aan te roepen vanuit de hoofdthread die het nieuwe venster maakt. Dit kan je doen door de Invoke() methode van een control. Het volgende stukje code doet dus wat ik wou:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private delegate void CreateConversationWindowHandler(Conversation conversation);
private void CreateConversationWindow(Conversation conversation)
{
    ConversationWindow window = new ConversationWindow(conversation);           
    window.Show();
}

private void OnConversationCreated(Messenger msn, ConversationChangeEventArgs e)
{
...
object[] args = new object[1];
args[0] = (e.Conversation);
// this == een windowsform
this.Invoke(new CreateConversationWindowHandler(CreateConversationWindow), args);
...
}

Phew ben wel blij dat het nu werkt was al bang dat ik met threadpools aan de slag moest gaan e.d. voor zoiets simpels.
Pagina: 1