[c#]invoke

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 11-09 12:47
Ik heb een hoofdform, hieronder hangt een class (met alleen idisposable interface) die scanner data afvangt (uit een compoort) en deze verwerkt.

Bij dit verwerken moet er een form getoond worden (in sommige gevallen).

De compoort-data wordt mbv het event SerialDataReceivedEventHandler uit SerialPort verwerkt. Deze draait echter in een andere thread, dus als ik wat wil laten zien moet ik invoken.

Nu is het zo dat mijn class nergens van erft wat een isynchronizeinvoke interface implementeerd, oftwel ik kan geen invoke doen. Als ik in deze handler een form wil laten zien, krijg ik niets te zien, omdat ie niet vanuit de goede thread is aangeroepen.

Ik wil dus een invoke kunnen doen vanuit mijn class en de isynchronizeinvoke interface implementeren. Optie 2 is dat ik een functie maak in mijn form die daar de invoke doet. Deze functie is echter geen event dus ik weet niet hoe ik dit kan oplossen.

EDIT:
Form werd wel getoond, alles deed het zoals het werkt. Echter als hij standaard niet op de voorgrond komt en er geen taakbalk melding van is, weet ik het natuurlijk nooit ;)

[ Voor 9% gewijzigd door elgringo op 05-06-2007 11:55 ]

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:34
Maak een event in die class die geraised wordt als je dat form moet laten zien.
Je hoofdform die - als ik het goed begrijp - je class gebruikt, kan dan op je instance van die class subscriben op dat event, en die form tonen als dat nodig is.
Dan moet je er gewoon voor zorgen dat, als je die event raised in je class, je daar checked of de 'Target' van die event een ISynchronizedInvoke dinges is, en of Invoken nodig is, en zoja, dan 'Invoke' je de delegate. Anders voer je 'm gewoon uit.

Zo dus ongeveer:
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
27
28
29
30
31
32
33
34
35
36
public class MyComStuff
{
      public event EventHander SomethingOccured;

      protected void OnSomethingOccured(object sender, EventArgs e )
      {
            if( SomethingOccured != null )
            {
                 Delegate[] dels = SomethingOccured.GetInvocationList();

                 foreach( Delegate d in dels )
                 {
                       if( d.Target is ISynchronizeInvoke && ((ISynchronizeInvoke)d.Target).InvokeRequired )
                       {
                            ((ISynchronizeInvoke)d.Target).Invoke ( ... )
                       }
                       else
                       {
                            d.DynamicInvoke ( ... );
                       }
                 }
            }         
      }

      public void Run()
      {
           Thread t = new ThreadStart (Work);
           t.Start();
      }

      private void Work()
      {
             ...
             OnSomethingOccured (this, EventArgs.Empty);
      }
}

[ Voor 51% gewijzigd door whoami op 05-06-2007 11:51 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Structuur is ongeveer zo?
code:
1
2
3
Hoofdform
  - Thread voor scanner
      - Form voor verwerking


Wat je moet doen is het een referentie naar serial port doorgeven aan het verwerkingsform en op dat form SerialDataReceivedEventHandler koppelen bijv SerialPort_SerialDataReceived.
In SerialPort_SerialDataReceived doe je vervolgens dit:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void SerialPort_SerialDataReceived(object sender, EventArgs e) {
    UpdateStatus(e);
}

protected delegate void UpdateStatusDelegate(EventArgs e);

protected void UpdateStatus(EventArgs e) {
   // Is dit een cross-thread operatie?
   if(this.txtOutputBoxje.InvokeRequired) {
      // Jups, dan dus Invoke gebruiken. Kan eventueel ook via this.Invoke()
      this.txtOutputBoxje.Invoke(new UpdateStatusDelegate(this.UpdateStatus), new object[] { e });
      // Hierna stoppen
      return;
   }

   // We zitten nu in dezelfde thread dus dit werkt nu.
   this.txtOutputBoxje.Text = "Output van de serial port";
}

Nu met Land Rover Series 3 en Defender 90


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 11-09 12:47
Ik maak nu het tweede form (voor input van wat data) in een tweede thread. Zodra deze klaar is wordt er een event afgevuurd die hoofdform pakt. Deze doet vervolgens een invoke en dan is het goed.

if broken it is, fix it you should