[C#] Cross-thread operation not valid

Pagina: 1
Acties:

  • microchip
  • Registratie: Maart 2004
  • Laatst online: 29-05-2021
Ik heb een simpel programma geschreven in Visual C# Express (Beta 2) met behulp van de SerialPort component. Ik heb een microcontroller op COM1 aangesloten die wat tekst verzend. Werkt allemaal prima als ik de tekst in een dialog box weergeef. Maar nu wil ik het in een textBox weergeven.
Daarvoor heb ik in de "DataRecieved" event van SerialPort1 dit regeltje code neergezet:

textBox1.Text = textBox1.Text + serialPort1.ReadExisting();

Maar als ik de programma compile en run, geeft hij de exception "System.InvalidOperationException" met het bericht "Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on." Ik heb in mijn programma nog helemaal niets met threads gedaan, dus het enige dat ik kan bedenken is dat serialPort zelf een thread maakt.

Mijn vraag dus: Hoe kan ik "textBox1.Text" wijzigen vanuit "serialPort1_DataReceived"?

[ Voor 6% gewijzigd door microchip op 29-05-2005 11:30 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Bij Java moet je dan een bericht (runnable) versturen op de event dispatching thread. Ik neem aan dat c# een vergelijkbare oplossing heeft.

code:
1
2
3
SwingUtilities.invokeAndWait(new Runnable(){
     public void run(){... hier je logica ...}
});

[ Voor 30% gewijzigd door Alarmnummer op 29-05-2005 11:34 ]


  • microchip
  • Registratie: Maart 2004
  • Laatst online: 29-05-2021
Hmm, ja. Maar heeft iemand een idee hoe dat zou heten in C#?

En, waarom maakt SerialPort een nieuwe thread?

Verwijderd

Beta 2 dus ook .Net 2 gok ik?
Kijk eens naar anonieme proceduren. Ik denk dat het zo heet. Ben niet zeker.

Ik ken niet zo veel van Java en weet niet wat die New Runnable() betekent. Hier alvast een link naar een goed artikel

http://www.theserverside....e.tss?id=AnonymousMethods

[ Voor 49% gewijzigd door Verwijderd op 29-05-2005 12:11 ]


Verwijderd

microchip schreef op zondag 29 mei 2005 @ 11:54:
En, waarom maakt SerialPort een nieuwe thread?
Omdat het wachten op data anders je programma zou blokkeren.
In het laatste .Net-magazine staat een relevant artikel.

Ik zou ff de help in duiken.
Wellicht dat er een event is die in de context van de gui-thread wordt uitgevoerd, zo niet dan moet je hier zelf iets voor implementeren.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:00
Je mag een windows - control enkel 'manipuleren' in de thread waar dat control ook gecreeërd was.
Je zult er dus moeten voor zorgen dat je een 'context switch' doet in die thread die dat event triggered.
Je moet dus je event-handler invoken op die andere thread.
In .NET 1.1 deed ik het zo:
[rml]whoami in "[ C#] button.Show() vanuit anderen Thread"[/rml]

Echter, in .NET 2.0 hebben ze nu ook een 'BackgroundWorker' class gemaakt die diezelfde dingen eigenlijk al allemaal voor jou implementeren.
Als die BackGroundWorker een beetje overkill is voor jou, dan kan je het op dezelfde manier oplossen zoals ik reeds getoond heb in die reply waar ik hier naar verwijs.
Echter, ipv dan te kijken of je 'Target' van je event-handler een 'Windows Control' is, kan je kijken of je 'Target' de ISynchronizeInvoke interface implementeert. Op die manier hoef je geen reference te leggen naar 'System.Windows.Forms' .

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void MyEventHandler(object sender, EventArgs e )
{

   if( TheEvent != null )
   {
       ISynchronizeInvoke t = TheEvent.Target as ISynchronizeInvoke;

       if( t != null )
       {
           t.Invoke (TheEvent, .... );
       } 
       else
       {
            TheEvent ( .... );
       }
   }

}

https://fgheysels.github.io/


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Mmmh, waarom schrijf je niet een eigen eventhandler in de thread waar je je control genereerd. Deze voeg je toe aan de methoden die aan worden geroepen door het event. Dit doe je uiteraard met een delegate.

If you are not wiping out you are nog pushing enough...

Pagina: 1