Sida 2 av 3

Re: Kört fast i C#

Postat: 18 juni 2009, 14:27:38
av bos
> Bos, vart kan jag läsa mer om det som du skrev om tidigare i ditt exempel?

Vad syftar du på? Att begränsa resurshantering mellan trådar?

Re: Kört fast i C#

Postat: 18 juni 2009, 14:59:15
av Gildebrand
Att jag skapar en funktion som innehåller koden för att skicka text över comporten, så att jag i klasserna bara behöver skriva

port1.open();
port1.write("Hej");
port1.close();

Re: Kört fast i C#

Postat: 18 juni 2009, 15:08:26
av bos
Jag fattar inte vad du vill åstadkomma.

I din kod som du skickade i det ursprungliga inlägget står det såhär:

Kod: Markera allt

port.Open();
port.Write("Hello");
port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);
och några rader ner även en port.Close().

Nu vill du ha hjälp med en funktion som gör att du bara behöver skriva port.open(), port.write(), port.close(), vilket är exakt de klassmetoderna du anropar i din originalkod.

Vad är problemet? Vad vill du göra?

Re: Kört fast i C#

Postat: 18 juni 2009, 15:28:46
av Gildebrand
Jag uppfattade det som att ni tyckte att jag inte tyckte att jag skulle ha denna kodrad i varje klass

Kod: Markera allt

            SerialPort port = new SerialPort(
            "COM1", 9600, Parity.None, 8, StopBits.One);
eftersom det skulle vara det som gjorde så att även World fick vänta 2 sekunder.

men jag förstod kanske fel. Jag är som ni märker total newbie vad gäller c#, började bara för några dagar sedan, så jag häger inte alltid med på vad ni menar.

Jag är bara ute efter en lösning på problemet som jag beskrev i första inlägget, och vart ganska många missförstånd från min sida när jag försökte förstå vad ni skrev.

Jag har funderat lite på att det är så att, när Sleep kommer, så ska det bara påverka klassen Hello, men att den av nån anledning fryser SerialPort också så att World inte kan använda den tills den vaknat igen.

Det jag vill åstadkomma är helt enkelt att World INTE ska vänta på att Hello körts klart för att kunna köras.

Re: Kört fast i C#

Postat: 18 juni 2009, 15:53:28
av bos
Jag hänvisar till http://elektronikforumet.com/forum/view ... 90#p467490 som jag skrev. Av nån anledning verkade du försöka köra den koden rakt av när den i själva verket är pseudo-kod. Pseudo-kod är (oftast inte) körbar, utan används för att förklara begrepp i generella termer. Men eftersom den tydligen inte hjälpte så ska jag försöka förklara i ord istället. Kom dock ihåg att jag inte programmerar i C#, så språkmässiga saker får du själv ta reda på hur du implementerar.

Till att börja med får du nog skrota din kod. Jag ser att du i Main startar två com-trådar, medan du i varje com startar ytterligare två trådar. Det innebär att du har två trådar som skapar två instanser av ett handle till serieporten, vilket innebär totalt fyra instanser. Detta kan nog vara en felkälla.

Annars är grundidén den här:

1. Skapa *ett* handle till serieporten. Enligt din egen kod är det såhär:

Kod: Markera allt

SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
port.Open()
Se till att variabeln "port" är global, dvs åtkomstbar från alla dina moduler. Hur du gör det i C# får du kolla upp själv, för jag har ingen aning. Förslagsvis skapar du den när Main() startas.

2. Skapa en global variabel "serialinhibit" och sätt den till 0. Denna variabel håller koll på om någon tråd pratar med serieporten.

3. Skapa en funktion som heter vad du vill, men säg write_to_serialport() för exemplets skull. Funktionen ska ta en sträng som argument, och ska se ut såhär:

Kod: Markera allt

function write_to_serialport(somestring) {
    // variabeln 'port' är den globala serieportsvariabeln
    // variabeln 'somestring' är funktionens argument
    // variabeln 'serialinhibit' är låsmekanismen till tråden

    while (serialinhibit = 1) {
      // denna while-loop körs i all evighet tills låset släpps
    }
    serialinhibit = 1;
    port.Write(somestring);
    port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);
    serialinhibit = 0;
}
Återigen, kolla upp i manualen hur du gör en funktion som tar emot argument. Jag vet inte hur man gör i C# och jag tänker inte kolla upp det åt dig.

4. I din klass Hello skriver du nu följande:

Kod: Markera allt

write_to_serialport("Hello");
Thread.Sleep(2000);
write_to_serialport("Tjosilosan");
och i klassen World

Kod: Markera allt

write_to_serialport("World");

Klart.

Re: Kört fast i C#

Postat: 18 juni 2009, 16:19:10
av johano
"serialnhibit" löses nog bäst med en Mutex i C#

/johan

Re: Kört fast i C#

Postat: 18 juni 2009, 16:29:55
av Nerre
Eftersom C# väl är objektorienterat är det väl bättre att göra så här:

Skapa en klass som är till för din hantering av serieporten. Vi kan kalla den Foo.

I konstruktorn till Foo öppnar man serieporten och startar en tråd som skickar data till serieporten när det dyker upp i en buffert.


Sen har Foo en metod, vi kan kalla den Skicka, som tar en sträng som argument.

Den anropas då med Foo.Skicka("Hello"). När den metoden anropas så stoppas argumentet (i det här fallet "Hello") in i bufferten som bakgrundstråden skickar data från.


Då vinner man ett par saker:

1. Ingen tråd blir "låst" i en evighetsloop bara för att porten är upptagen, eftersom det bara är en tråd som skriver till porten. De andra trådarna skriver till en buffert (via Foo.Skicka-metoden, som såklart bör ha stöd för att hantera "full buffert" och liknande fel).

2. Man slipper en global variabel (objektet av klassen Foo blir såklart globalt, men ett globalt objekt är vettigare än en global variabel).

Re: Kört fast i C#

Postat: 18 juni 2009, 17:19:39
av Gildebrand
Ska se om jag förstod det där rätt

Först alltså en klass där koden för att skicka kommandon ligger. Och då ska man kunna lägga in Foo.Write("Hello") på en knapp, så när man trycker på den så skickar Foo klassen ut Hello?

Kod: Markera allt

private void Foo();
{

SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
port.Open()

port.Open();
port.Write("vad ska det stå här för att den ska skicka koden den tar emot?");
port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);
port.Close();
}
Nä det är väl helt fel?
Men är man n00b så är man :razz:
Kan du visa något kodexempel så kanske jag kan tillämpa det på det här?

Re: Kört fast i C#

Postat: 18 juni 2009, 17:31:58
av hh
Inte för att vara otrevlig, men det verkar som om du skulle behöva läsa på lite om objektorienterad programmering.

Att köra flera trådar (så att det är någon vits med det) är inte helt enkelt, och om man inte kan grunderna blir det riktigt svårt.

Kolla upp så att du i varje fall förstår koncepten med klasser, objekt, metoder och konstruktorer - det är inte svårt, men det är nödvändigt om du tänker bygga upp ett större projekt.

Re: Kört fast i C#

Postat: 18 juni 2009, 18:34:55
av Gildebrand
Kan du rekommendera nån sida där man kan läsa om det då? Gärna med mycket kodexempel.

Re: Kört fast i C#

Postat: 18 juni 2009, 19:02:20
av hh
Jag sökte snabbt och tyckte den här verkade vettig:

http://www.csharp-station.com/Tutorial.aspx

Allt verkar vara illustrerat med kod, och avsnitten är så korta att man säkert hinner med hela på en kväll, förutsatt att man greppar allt på första försöket.

Re: Kört fast i C#

Postat: 18 juni 2009, 22:40:41
av Jeppsson
Angående tidsintervallet som du försöker få till så rekommonderar jag dig att använda timers istället.

Jag hade liknande problem som dig när jag använde mig av sleep funtionen.

Kolla min tidigare tråd... C# programmera med tidsintervall?

Re: Kört fast i C#

Postat: 18 juni 2009, 23:16:28
av Gildebrand
Jeppsson, Hur ska man då ersätta sleep med en timer? Om jag har skapat en timer med en intervall på 2000 ms. Visst ska jag använda mig utav tick på något sätt efter timer1.start?

Re: Kört fast i C#

Postat: 18 juni 2009, 23:36:09
av Jeppsson
Det står rätt så bra förklarat i länken i min tråd.... Förklarande länk hos C#-Corner

Lägg till timer och sedan dubbelklicka på den föra in koden vad den skall göra.

Re: Kört fast i C#

Postat: 19 juni 2009, 00:19:01
av Gildebrand
hur gör jag för att com.cs ska hitta på timer1 som ligger i form1.cs?