[C#] Roep een methode aan in een andere thread

Pagina: 1
Acties:
  • 132 views sinds 30-01-2008
  • Reageer

  • AquilaDus
  • Registratie: Januari 2004
  • Laatst online: 21-03 00:33
Ik zit met het volgende probleem. Ik heb een netwerkapplicatie die uit 2 threads bestaat. De hoofdthread(dit is de standaard thread waar de gui in zit e.d.) en een thread voor het ontvangen van het netwerkverkeer.
Als er bepaalde data via het netwerk binnenkom wil ik een nieuw form maken. Als ik dit doe in de netwerkthread blokkeert dit forum omdat de thread blokkeert als er geen netwerkinput binnenkomt.
Nu zou ik dus een methode in de mainthread willen aanroepen die dan dit form aanmaakt zodat deze de eigenaar is.

Heeft iemand dus een idee hoe ik dus een methode in de mainthread kan aanroepen(asynchroon natuurlijk) vanuit een andere thread.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
Je zou eventueel met delegates kunnen werken.

https://fgheysels.github.io/


  • AquilaDus
  • Registratie: Januari 2004
  • Laatst online: 21-03 00:33
whoami schreef op 28 februari 2004 @ 15:34:
Je zou eventueel met delegates kunnen werken.
Je in mijn speurtocht op het web kwam dat ook al tegen, maar ik wist niet zeker of die dus buiten threads om werkten.
Heeft er iemand een goede tutorial wat delegates betreft, want ik kwam er niet echt achter hoe je ze moest gebruiken en wat het idee er achter was.

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Een delegate is een functiepointer, that's all :)

Je blokkert toch niet de main-thread? Want daarop moet je zo wie zo al je gui dingen uitvoeren (het gui gedeelte van het .net framework is voor het grootste gedeelte niet thread-safe). En op je gui controls heb je een methode om een bepaalde "delegate te invoken".

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • AquilaDus
  • Registratie: Januari 2004
  • Laatst online: 21-03 00:33
Infinitive schreef op 28 februari 2004 @ 15:47:
Een delegate is een functiepointer, that's all :)

Je blokkert toch niet de main-thread? Want daarop moet je zo wie zo al je gui dingen uitvoeren (het gui gedeelte van het .net framework is voor het grootste gedeelte niet thread-safe). En op je gui controls heb je een methode om een bepaalde "delegate te invoken".
Nee, de netwerkthread blokkeert, maar deze thread heeft dus ook het nieuwe form gecreeerd. Dus het form draait in de netwerkthread.

Maar als een delegate een methodepointer is en je roept die aan in die netwerkthread krijg je dan niet gewoon hetzelfde probleem dat die code van die methode door de netwerkthread wordt uitgevoerd en niet door de mainthread?

  • Juicy
  • Registratie: December 2000
  • Laatst online: 05:27
Zoals infinitive al zegt dien je met een invoke de actie over te hevelen naar de GUI/Main thread. Hierdoor komt ook direct je aparte thread weer beschikbaar.

Zie ook "invoke".

-


  • AquilaDus
  • Registratie: Januari 2004
  • Laatst online: 21-03 00:33
Juicy schreef op 28 februari 2004 @ 15:53:
Zoals infinitive al zegt dien je met een invoke de actie over te hevelen naar de GUI/Main thread. Hierdoor komt ook direct je aparte thread weer beschikbaar.

Zie ook "invoke".
Ja, ik had algezien dat er aan een form een invoke methode zit. Dus ik heb geprobeert om op een form uit de mainthread deze invoke aan te roepen. Deze invoke heeft ook een delegate nodig als parameter, maar ik heb geen idee hoe ik dan een delegate maak en die delegate dus koppel aan een methode.
Als iemand mij een voorbeeld zou willen geven dan zou ik ehel dankbaar zijn.

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
Zoek eens in de .NET help naar delegates, of spit die invoke method eens verder uit.
Je kan aan die Invoke een delegate meegeven van het type MethodInvoker. Dat wil dus zeggen dat de method die je aan die delegate koppelt, aan de MethodInvoker signature moet voldoen.
Die signature is gewoon de simpelste die er is:
code:
1
void MethodInvoker()


Die invoke roep je dan dus ongeveer als volgt aan:
code:
1
MyForm.Invoke (new MethodInvoker(MyFunctionBlaat));


Dan moet je natuurlijk nog MyFunctionBlaat gaan schrijven:
code:
1
2
3
public void MyFunctionBlaat()
{
}


Als je een method nodig hebt die parameters heeft, dan kan je natuurlijk ook altijd je eigen delegate definitie gaan maken en gebruiken.

https://fgheysels.github.io/


  • AquilaDus
  • Registratie: Januari 2004
  • Laatst online: 21-03 00:33
Dankje whoami, het werkt perfect!

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:40
Ik denk dat je het zo moet kunnen oplossen:

Dit is bv een class die op een andere thread uitgevoerd wordt:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class MyClass
{
      private Thread _t;
      private MethodInvoker _mi;
      private System.Windows.Forms.Form _frm;

      public MyClass(MethodInvoker methodInv, System.Windows.Forms.Form parentForm)
      {
           _frm = parentForm;
           _mi = methodInv;
           _t = new Thread(new ThreadStart(MyThreadFunction));
      }

      public void StartIt()
      {
          _t.Start();
      }

       private void MyThreadFunction()
       {
            if( _mi != null )
            {
                 _frm.Invoke(_mi);
            }
       }
}


In je GUI doe je dan bv dit:
code:
1
2
3
4
5
6
7
8
9
10
11
public void button1_click(object sender, EventArgs e)
{
       MyClass c = new MyClass(new MethodInvoker(BlaatMethod));
       c.StartIt();
}

private void BlaatMethod()
{
     Form3 frm = new Form3();
     frm.Show();
}

https://fgheysels.github.io/


  • AquilaDus
  • Registratie: Januari 2004
  • Laatst online: 21-03 00:33
Bedankt voor alle moeite, maar zoals je boven al misschien al gelezen hebben de kleine regeltjes al geholpen die je daarboven gepost hebt.
Pagina: 1