Kört fast i C#

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Användarvisningsbild
Gildebrand
Inlägg: 1108
Blev medlem: 8 maj 2009, 21:40:49
Ort: Falun

Kört fast i C#

Inlägg av Gildebrand »

Hejsan!
Ni kanske minns att jag tidigare sökte ett styrsystem för projektorer och kringutrustning. Jag hittade inget som jag gillade så det vart till att koda eget istället. Och nu har jag stött på problem.

först koden, sen problemet

COM.CS

Kod: Markera allt

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Threading;

namespace WindowsFormsApplication1
{
    class com
    {
        public void Main(string[] args)
        {
            ThreadStart tsHello = new ThreadStart(Hello);
            ThreadStart tsWorld = new ThreadStart(World);

            Thread tHello = new Thread(tsHello);
            Thread tWorld = new Thread(tsWorld);

            tHello.Start();
            tWorld.Start();

            tHello.Join();
            tWorld.Join();
        }

        public void Hello()
        {
            SerialPort port = new SerialPort(
            "COM1", 9600, Parity.None, 8, StopBits.One);

            port.Open();
            port.Write("Hello");
            port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);

            Thread.Sleep(2000);

            port.Write("Tjosilosan");
            port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);
            port.Close();
        }
        public void World()
        {
            SerialPort port = new SerialPort(
            "COM1", 9600, Parity.None, 8, StopBits.One);

            port.Open();
            port.Write("World");
            port.Write(new byte[] { 0x0A, 0xE2, 0xFF }, 0, 3);
            port.Close();
        }
    }
}
och Form1.CS

Kod: Markera allt

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        com myCom = new com();

        public void Main(string[] args)
        {
            ThreadStart tsHello = new ThreadStart(myCom.Hello);
            ThreadStart tsWorld = new ThreadStart(myCom.World);

            Thread tHello = new Thread(tsHello);
            Thread tWorld = new Thread(tsWorld);

            tHello.Start();
            tWorld.Start();

            tHello.Join();
            tWorld.Join();
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            myCom.Hello();
            myCom.World();
        }

    }
}
Som ni ser finns det i com.cs två klasser. Klassen Hello skickar först ut "Hello" på COM1, för att sedan, 2 sekunder senare skicka ut "Tjosilosan" på samma port. Så långt funkar det bra.

Klassen World skickar bara ut "World" på COM1. Den funkar också finfint.

Men om jag nu kör båda samtidigt, alltså det som händer när jag trycker på button4, då fryser thread.freeze alltihop så att det som kommer in i hyperterminal blir

Kod: Markera allt

Hello
               â Tjosilosan
                               â World
                                         â
Mellan att Hello och Tjosilosan dyker upp går det alltså två sekunder, och World kommer direkt efter Tjosilosan.

Det är alltså inte så jag vill ha det, jag vill inte att World ska vänta med att skickas, utan den ska komma in samtidigt som Hello, och sen, 2 sekunder senare dyker Tjosilosan upp.

Jag försökte lösa det med hjälp av multithreading, men utan någon vidare lycka. Jag tänkte att då skulle thread.freeze bara frysa Hello, och inte World, men så är inte fallet.
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Kört fast i C#

Inlägg av johano »

Tror du behöver göra Close() *innan* du anropar Thread.Sleep i Hello-tråden.

/johan
Användarvisningsbild
Gildebrand
Inlägg: 1108
Blev medlem: 8 maj 2009, 21:40:49
Ort: Falun

Re: Kört fast i C#

Inlägg av Gildebrand »

Det har jag provat. Var visserligen tvungen att öppna den igen efter sleep, men det borde inte göra någon skillnad.

Funkar inte ivarjefall.
Nerre
Inlägg: 27150
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Kört fast i C#

Inlägg av Nerre »

Det kan väl inte vara det smartaste att ha flera olika grejer som samtidigt ska pilla på samma serieport? Serieporten är ju en resurs som inte har några rutiner för att "delas".


Skriv hanteringen av serieporten separat, i huvudprogrammet, kanske rentav interruptstyrt, och låt dina klasser ställa sin text "i kö" hos den funktionen (eventuellt tillsammans med nån tidskod).
bos
Inlägg: 2308
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Kört fast i C#

Inlägg av bos »

Nu kan jag inte C#, men eftersom du i var sin klass skapar en ny instans till din serieport innebär det att du får två separata hanterare som du sen pillar på i tid och otid i var sin tråd. Det är Fult, Felt och Dumt. Skapa *ett* handle till serieporten och använd detta globalt genom en wrapper och en kö.

Ungefär såhär (pseudokod):

Kod: Markera allt

serialhandle = SerialPort();
serialinhibit = 0;

function write_to_serial(text) {
    while (serialinhibit) {
       // evig paus tills serieporten blir fri
    }
    serialinhibit = 1;
    
    ...kod för att skriva till serieporten...
    ...vars handle finns i 'serialhandle'...

    serialinhibit = 0;
}

void Hello() {
   write_to_serial("Hello");
}

void World() {
   write_to_serial("World");
}

function main() {
   thread_start(Hello);
   thread_start(World);
}
Användarvisningsbild
Gildebrand
Inlägg: 1108
Blev medlem: 8 maj 2009, 21:40:49
Ort: Falun

Re: Kört fast i C#

Inlägg av Gildebrand »

Man tackar så mycket :) Ska prova det. Men borde inte Thread.Start ligga först?
Tänkte att jag kunde använda mig utav funktionen SerialPort som finns i Visual C# 2008.

Trodde det bara skulle gå att skriva SerialPort1.Write(Hej); men det gillade den inte
bos
Inlägg: 2308
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Kört fast i C#

Inlägg av bos »

> Men borde inte Thread.Start ligga först?

Hur ska jag veta det? Jag kan som sagt inte C#. Jag pratar generellt om hur man ska bete sig med trådar och delade resurser.

> Tänkte att jag kunde (...)
> Trodde det bara (...)

Tittade du i C#-referensen efteråt för att se varför det inte gick?
sodjan
EF Sponsor
Inlägg: 43231
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Kört fast i C#

Inlägg av sodjan »

> ...men det gillade den inte


"Gillade inte" är en fullständigt värdelös beskrivning av vad som (eller som inte) hände !
Användarvisningsbild
Gildebrand
Inlägg: 1108
Blev medlem: 8 maj 2009, 21:40:49
Ort: Falun

Re: Kört fast i C#

Inlägg av Gildebrand »

Sorry, för att jag inte berättade lite mer. Den sa att Hej does not appear in the current context, men det löste sig när jag la till skrev ("Hej") istället för (Hej).

Det borde väl bli samma sak som bos skrev innan i sitt kodexempel, bara utan all extra kod. serialport1 pekar ju på en funktion som finns inbäddad i programmet, och write_to_serial pekar på en funktion som man skapat.

Nu har jag SerialPort1 i Form1.cs, och vill kunna anropa den funktionen från com.cs.
Hur gör jag för att com.cs ska hitta SerialPort1 som ligger i form1.cs?
bos
Inlägg: 2308
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Kört fast i C#

Inlägg av bos »

> det löste sig när jag la till skrev ("Hej") istället för (Hej).

Jag hoppas du förstår varför.

> write_to_serial pekar på en funktion som man skapat.

Vadå "pekar på en funktion"? write_to_serial() i min pseudokod *är* en funktion. Anropar du en funktion till i funktionen, eller vad menar du?
Användarvisningsbild
Gildebrand
Inlägg: 1108
Blev medlem: 8 maj 2009, 21:40:49
Ort: Falun

Re: Kört fast i C#

Inlägg av Gildebrand »

Oj, vart hel fel där.

Men har du nån idé om hur jag får com.cs att hitta SerialPort1 i form1.cs?
bos
Inlägg: 2308
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Kört fast i C#

Inlägg av bos »

"extern", "include", "import", "external functions" är sökord jag skulle kolla efter i manualen.
Användarvisningsbild
Icecap
Inlägg: 26612
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Kört fast i C#

Inlägg av Icecap »

När jag skriver C++ i Borland C Builder kommer man åt funktioner på andra form vid att skriva Formx->Önskat_Funktion osv.
perra_e
Inlägg: 983
Blev medlem: 13 februari 2009, 16:26:53
Ort: Jönköping

Re: Kört fast i C#

Inlägg av perra_e »

Gildebrand skrev:Oj, vart hel fel där.

Men har du nån idé om hur jag får com.cs att hitta SerialPort1 i form1.cs?
Är det av någon speciell anledning du valt att lägga SerialPort1 i formuläret? Den om något borde väl ligga i klassen för att hantera kommunikationen.
Användarvisningsbild
Gildebrand
Inlägg: 1108
Blev medlem: 8 maj 2009, 21:40:49
Ort: Falun

Re: Kört fast i C#

Inlägg av Gildebrand »

Bos, vart kan jag läsa mer om det som du skrev om tidigare i ditt exempel? funkade inte direkt rakt av men det verkar vara en bra idé att prova.

Funderade lite på en grej, när jag klickar på knappen för klassen Hello och World, så fryser hela programmet i 2 sekunder. Så ska det väl inte vara? har jag inte gjort fel med trådarna nånstans då?
Skriv svar