Avatar billede acidduck Nybegynder
19. marts 2006 - 19:26 Der er 4 kommentarer

Windows.Form fryser ved Monitor.Wait()

Hejsa. Jeg har et problem med en Windows.Form der fryser, når jeg afvikler en metode som blokker i et stykke tid inden den returnerer.

Derfor valgte jeg at lade metoden køre i en tråd for sig:

public void MakePayment(double anAmount) {
    // Konvertere kroner til øre
    amount = (int)anAmount * 100;
   
    GfxGUI gui = new GfxGUI();
    gui.Visible = true;               

    Thread thread = new Thread(new ThreadStart(DoPayment));
    thread.Start();
           
    lock (this) {
      Monitor.Wait(this);}
}

private void DoPayment() {
    result = kald_til_ekstern_metode_der_blokker();           

    lock (this) {
      Monitor.Pulse(this);}
}

MakePayment må IKKE returnere før tråden er færdig - og jeg har derfor forsøgt mig med Wait/Pulse.
Desværre ser det ud til at kaldet til Wait får GUI'en til at fryse. Jeg har derfor forsøgt også at køre GUI'en i
en tråd for sig, men den fryser stadig - eller også ved jeg bare ikke hvordan man gør det rigtigt!

Hvad kan jeg ellers prøve?
Avatar billede arne_v Ekspert
19. marts 2006 - 19:48 #1
det var vel nemmere at bruge

public void MakePayment(double anAmount) {
    // Konvertere kroner til øre
    amount = (int)anAmount * 100;
 
    GfxGUI gui = new GfxGUI();
    gui.Visible = true;             

    Thread thread = new Thread(new ThreadStart(DoPayment));
    thread.Start();
    thread.Join();
}

private void DoPayment() {
    result = kald_til_ekstern_metode_der_blokker();         
}
Avatar billede arne_v Ekspert
19. marts 2006 - 19:49 #2
men koden giver jo ingen mening

når du alligevel venter på tråden så er der jo ingen grund til at starte en tråd
Avatar billede acidduck Nybegynder
19. marts 2006 - 20:15 #3
Grunden til jeg starter en tråd er at min GUI ellers fryser, hvilket også sker med thread.Join().

Det er lykkes mig med:
new Thread(new ThreadStart(gui.ShowGUI)).Start(); 

Hvor ShowGUI() kalder ShowDialog(). Jeg kan nu bare kalde DoPayment() uden at køre den i en tråd.
Avatar billede tuxic Nybegynder
17. april 2006 - 23:44 #4
Er der ikke to issues her? For det første hvis et winforms programs hovedtråd arbejder, bliver GUI'en ikke opdateret (det er jo hovedtråden der står for opdateringen/messagepump).

For det andet, koden øverst låser vel pga af de to locks. Typisk sker der vel:
* hovedtråden tager låsen og venter på Pulse-kaldet.
* DoPayments tråd bliver færdig med kald til blokerende metode.
* DoPayments tråd prøver at tage låsen. Dvs den står og venter til låsen frigives.
* Låsen frigives først når Pulse-kaldet gennemføres.
Så det er en klassisk deadlock situation.

(Teoretisk kunne der også ske det, at lige efter den nye tråd er startet op, skiftes hovedtråden af processoren og den kommer ikke tilbage på processoren før den nye tråd er helt færdig, så deadlock'en er ikke logisk. Omend den sikkert opleves 'konsistent'.)

Hvorfor skal MakePayment metoden venter på at arbejdet i DoPayment metoden er færdigt?
Måske kunne du i stedet disable kontroller eller tilsvarende hvis brugeren ikke må (kunne) foretage sig noget før DoPayment er færdig.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester