Trådhantering vid Seriellkommunikation (C# VS 2008)

Permalänk
Medlem

Trådhantering vid Seriellkommunikation (C# VS 2008)

Hej på er,

Jag har fått äran att ta över en applikation (C# VS 2008) som inte fungerar och jag har hittills inte lyckats lösa problemen men jag tror jag vet vad som ligger bakom, dock vet jag inte hur jag löser det ännu, det är här ni kommer in

När applikationen (Windows Forms) startar kopplar upp sig mot en skrivare, kortläsare (kort med magneträmsa), och scanner. Kommunikationen sker med hjälp av System.IO.Ports.SerialPort och det går bra att koppla upp sig och öppna kommunikationen men...

Inloggning i applikationen sker med hjälp av kort som man drar i en kortläsare, kortläsaren sänder då information till applikationen som man tar emot via eventet DataReceived. När detta sker skall kontroll ske om användaren är behörig och därefter skall kontroll ske om skrivaren fungerar. Det är här det går åt skogen. Precis som med kortläsaren tar applikationen emot meddelande från skrivaren via dess eget event för DataReceived. Problemet är att när man i DataReceived för kortläsaren skickar InitPrinter kommandot till skrivaren för att den skall tala om hur den mår så händer ingenting. Status på skrivaren förblir oförändrat. Då skrivaren normalt sett inte svarar blixtsnabbt sätts en System.Timers.Timer till 2 sekunder efter det att kommandot skickats till skrivaren, men det spelar ingen roll om Timern sätts till 10 sekunder, skrivarens status förblir oförändrad. Användaren som loggar in måste få ett kvitto på att den är inloggad, annars får inte applikationen köras.

Analys:
Så vitt jag förstått körs kommunikationen System.IO.Ports.SerialPort i egna trådar och det betyder ju då att kortläsare och skrivare körs separat från varandra, även Timer kör i en egen tråd. Problemet tycks då för mig vara att då skrivaren lever i en tråd och när kortläsaren som lever i sin tråd skall kommunicera med skrivaren så går inte det som det är nu för trådarna är separata...eller vad kan det beror på? Hur löser man detta? I detta skede av applikationen behövs ingen uppdatering av GUI så det kan man bortse ifrån, å andra sidan löses ju det med Invoke. Men men, hur kan jag få en seriell enhet att kommunicera med en annan seriell enhet från sitt DataReceived event?

Tack på förhand alla grymma!!!

Visa signatur

ASUS ROG Strix X570-F, AMD Ryzen 9 5900X, ASUS GTX 1080 Ti Strix Gaming OC, 32GB G.Skill Trident Z Neo CL16 3600MHz, Arctic Freezer II 240, Seasonic Prime Titanium 850W, Phanteks Enthoo Evolv X, 2x Samsung 970 EVO Plus 1TB, Seagate Firecuda 2TB, Seagate Ironwolf 4TB, ASUS PG278Q

ASUS ROG Crosshair VI Hero, AMD Ryzen 9 3900X, ASUS RTX 2060 Dual OC, 16GB G.Skill Flare X CL14 3200 MHz @3200 MHz, Arctic Freezer 240, Seasonic Prime Titanium 850W, Phanteks Eclipse P400S Glass, Samsung 960 Pro 512GB, Samsung 850 Pro 512GB, Seagate Ironwolf 4TB, ASUS PG278Q

ASUS Maximus V GENE, Intel i7 3770K @ 4,6 GHz (1.190 V), EVGA GTX 670 FTW SLi, 8GB G.Skill TridentX CL10 2400 MHz, Samsung 850 Pro 512GB, Samsung 840 Pro 256GB, Corsair Hydro H100i, Corsair AX860i, Fractal Design Define R4W, ASUS PG278Q

Permalänk
Hedersmedlem

Bland de enklare lösningarna borde väl vara att använda gui-tråden för att samordna de andra trådarna?

Permalänk
Medlem

Jag är som sagt ingen trådkung. Den som byggt appen från början skapar inga trådar manuellt utan alla sköts av .NET så vitt jag vet. Om man inte själv skapat en GUI tråd, hur kan jag då få tag i den?

Hur som helst kom jag på en lösning på problemet men om det är en bra och hållbar lösning vet jag inte, se nedan.

Genom att manuellt stoppa eventet för kortläsaren med...

public static System.Threading.ManualResetEvent manResEvent = new System.Threading.ManualResetEvent(false);

...och då påtvinga skrivaren att exekvera sitt event och sedan återgå till kortläsareventet så snart den önskade koden för skrivarens event utförts fungerar det som jag önskar. Sätter även en timer som också kan få exekveringen för kortläsaren att fortsätta om skrivaren tex skulle vara avslagen för då kommer inget event för den att ske.

Finns det en bättre lösning en denna är jag mycket intresserad.

Tack på förhand

Visa signatur

ASUS ROG Strix X570-F, AMD Ryzen 9 5900X, ASUS GTX 1080 Ti Strix Gaming OC, 32GB G.Skill Trident Z Neo CL16 3600MHz, Arctic Freezer II 240, Seasonic Prime Titanium 850W, Phanteks Enthoo Evolv X, 2x Samsung 970 EVO Plus 1TB, Seagate Firecuda 2TB, Seagate Ironwolf 4TB, ASUS PG278Q

ASUS ROG Crosshair VI Hero, AMD Ryzen 9 3900X, ASUS RTX 2060 Dual OC, 16GB G.Skill Flare X CL14 3200 MHz @3200 MHz, Arctic Freezer 240, Seasonic Prime Titanium 850W, Phanteks Eclipse P400S Glass, Samsung 960 Pro 512GB, Samsung 850 Pro 512GB, Seagate Ironwolf 4TB, ASUS PG278Q

ASUS Maximus V GENE, Intel i7 3770K @ 4,6 GHz (1.190 V), EVGA GTX 670 FTW SLi, 8GB G.Skill TridentX CL10 2400 MHz, Samsung 850 Pro 512GB, Samsung 840 Pro 256GB, Corsair Hydro H100i, Corsair AX860i, Fractal Design Define R4W, ASUS PG278Q