Avatar billede 2705 Nybegynder
23. juli 2009 - 09:45 Der er 10 kommentarer og
1 løsning

Vent i forløkke til event er behandlet

Hej

Jeg har en en IR modtager, som skal lære nolge koder fra en fjernbetjening.

Jeg har lavet et stykke kode hvor jeg trykker på en knap og derefter har 5 sekunder til at trykke på knappen (Learn) på fjernbetjeningen. Ligeså snart jeg trykker modtages et event med IR koden.
Det jeg gerne vil er at udvide koden så jeg kan learne flere koder i træk uden at skulle trykke på Learn-knappen hver gang - dvs. de skal komme lige efter hinanden. Antallet af koder jeg skal learne bestemmes ud fra items i en liste.

Kode:

for (itemIndex = 0; itemIndex < listViewIRAdded.Items.Count; itemIndex++)
{
  LearnNext();
  //Gå ikke videre med den næste før den første er learned.
  //while (!isLearned) { Thread.Sleep(10); }
}

- Jeg itererer igennem listen for at få hvert item.
- Jeg kalder en funktion der starter learning.
- TODO: Vent med at gå videre i løkken før jeg har modtaget og behandlet mit event med data.

Det hele udvikles i C# på .NET 3.5
Avatar billede 2705 Nybegynder
23. juli 2009 - 10:31 #1
Skulle have været:

...har 5 sekunder til at trykke på knappen på fjernbetjeningen.
Avatar billede bvli Praktikant
23. juli 2009 - 12:08 #2
Du kunne prøve at se på System.Threading.AutoResetEvent.

Deklarér en variabel af typen, som kan tilgåes både af den metode som "learner" og din løkke.

I din "Learn" metode kalder du Set() metoden på eventet når den er færdig med at learne og i løkken kalder du WaitOne() metoden på eventet når du har sat den i gang med at learne.
Avatar billede 2705 Nybegynder
23. juli 2009 - 13:21 #3
Jeg tror du har ret at det er AutoResetEvent jeg skal have fat i.
Har prøvet at kigge lidt på nogle eksempler, men synes det ser indviklet ud.
Kunne du prøve at give et eksempel på hvordan det skulle implementeres?

Altså noget á la dette?:

AutoResetEvent autoEvent = new AutoResetEvent(false);

for (itemIndex = 0; itemIndex < listViewIRAdded.Items.Count; itemIndex++)
{
  LearnNext();
  //Gå ikke videre med den næste før den første er learned.
  RegisteredWaitHandle handle = ThreadPool.RegisterWaitForSingleObject(autoEvent, EventHandler, "TEST", 3000, false);

  autoEvent.Set(); 
}

og mit event:

private void DataReceived(string data)
{
  Behandl data.
  .
  .
  .

  Sæt et flag.
}
Avatar billede 2705 Nybegynder
23. juli 2009 - 13:27 #4
Eller sådan:

for(...)
{
  LearnNext();
  autoevent.waitone();
}

event:

void DataReceived(string data)
{
  autoevent.set();
}
Avatar billede bvli Praktikant
23. juli 2009 - 13:35 #5
AutoResetEvent are = new AutoResetEvent(false);
[...]

for(;;) {
  LearnNext();
  are.WaitOne();
}

void DataReceived(string data) {
  //Behandl data
  are.Set();
}


Jeg går her ud fra, at din "LearnNext()" sætter en eller anden lytning i gang i en anden tråd, som så kalder DataReceived(string). Imens blocker den tråd din løkke kører i indtil DataReceived kalder are.Set();
Avatar billede 2705 Nybegynder
23. juli 2009 - 13:42 #6
Ja, LearnNext starter en anden tråd med kommunikationen til IR learneren. Når der modtages data på IR learneren raises DataReceived eventet.

Problemet ved at gøre dette er at når jeg kalder are.WaitOne() blokerer jeg den tråd som skal modtage eventet - så den vil stå og vente for evigt.

Så man skal vel lave det i en helt tredje tråd?
Avatar billede bvli Praktikant
23. juli 2009 - 13:59 #7
DataReceived bliver vel kaldt i den tråd som lytter efter og behandler data? WaitOne() kaldet blokerer jo kun løkken. Og den vil fortsætte når dit event bliver signaleret af den tråd som afvikler DataReceived.
Avatar billede 2705 Nybegynder
23. juli 2009 - 17:53 #8
Der lyttes på DataRecived eventet i mainformen, hvor løkken også ligger. Så når WaitOne() kaldes blokerer den for mainformen så den ikke kan modtage events.

Se evt.
http://stackoverflow.com/questions/847423/c-threading-and-using-autoresetevent/847457#847457

Så man er vel nødt til at give mainformen tid til at håndtere events.
Avatar billede bvli Praktikant
23. juli 2009 - 20:35 #9
ah.. BackgroundWorker er din ven. Den metode løkken er skal du starte op i BackgroundWorkeren..
Avatar billede 2705 Nybegynder
23. juli 2009 - 22:56 #10
Jeg har fundet en alternativ løsning ved at kalde LearnNext() en gang og når jeg så modtager eventet kalder jeg LearnNext() igen i den.

Men smid et svar, så får du point.

Men vil lige prøve backgroundWorkeren, har jeg ikke brugt før.
Tak for hjælpen!
Avatar billede bvli Praktikant
23. juli 2009 - 23:14 #11
Okay - lyder som en workaround :)
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