Release-ben kifagy a Threading C#

Release-ben kifagy a Threading C#
2016-11-03T10:56:40+01:00
2016-11-03T14:24:46+01:00
2022-10-15T23:25:46+02:00
ztajti
Sziasztok!

Adott egy olyan problémám, ahol a program, Visual Studion belüli debug esetén (F5) hiba nélkül lefut, el is végzi a feladatát (csv-ből sqlbe tölt), de amikor VS-en kívülről szeretném indítani, a program lefagy.

Arra kérlek benneteket, hogy nézzétek meg, hogy ez mitől lehet!

Köszönöm!

Forráskód: [C#] SqlSync - Kifagy Releaseben - Pastebin.com
Mutasd a teljes hozzászólást!
Na, ez konkrét hiba: ez azért lehet, mert a SyncWindow() konstruktorban indítod a szálad, ami már próbál Invoke()-ot hívni az lb_Stat control-ra, az ablak viszont még nem jött létre.

Próbáld a thread-et a Form.Load eseménykezelőben indítani, addigra már létre kell, hogy jöjjön!
Mutasd a teljes hozzászólást!

  • Szia!

    Én első körben azt javaslom, főleg, mivel V. Studio alatt nem jön elő a hibád, hogy szervezz a programodba kivételkezelést. Ezzel elérheted azt, hogy

    1) nem fagy ki a programod, csak úgymond megáll a működése a hibát okozó pontnál, jó esetben befejezi az adott szubrutint vagy függvényt, és újból lehet dolgozni vele, újrapróbálni, stb.

    2) a kivételkezelés megfelelő egységébe (catch) írathatsz log-fájlt, így a probléma okozójáról, körülményeiről megtudhatsz infókat

    Ez nem csak nekünk segítség, ill. a segítőknek, de ha kikísérletezed a működését és használatát, minden későbbi munkádnál jól jöhet bármikor.

    Pl. jelen esetben is egy konkrét hibaüzenetet vagy hibakódot tudnál itt prezentálni, nem csak annyit, hogy "kifagy", mert annak tízezer oka lehet.
    Mutasd a teljes hozzászólást!
  • Thread t = new Thread(construct); t.Start();
    bekerült egy try-catch kivételkezelésbe, s próbálkozom.
    Kifagy = "A Sync.exe hibát érzékelt, s ezért leállt!"

    folyamatosan írom a kivételkezeléseket és a hibalogokat, hogy mi lehet az adott hiba, hogy jobban megközelíthető legyen a probléma.

    Köszönöm!
    Mutasd a teljes hozzászólást!
  • Nem vagyok otthon C#-ban, de más nyelvekben a Thread-on belül csak speciális konstrukciókon keresztül szabad a képernyőt (az lb_Stat listát) módosítani. Javaslom, hogy ezt nézd meg.
    Ha nem ez a gond, akkor - mivel önálló futásnál nincs debugger - különböző soroknál helyezz el saját "logolást". Pl. egy fájlba írd bele, épp hol tart a program, vagy az ablakod fejlécébe írd bele. Így látni fogod, hol fagy le.
    Mutasd a teljes hozzászólást!
  • A kódod - már elnézést - teljes káosz és valahol deadlock-ra futhat, ezért fagyhat meg. Ha fagyás alatt kezeletlen exception-t értesz, az inkább összeomlás, ez esetben valóban a háttér-szálad rántja magával az egész alkalmazást.

    Néhány általános tipp, mert ezt egyszerűbb elölről rendesen megírni, mint javítgatni:

    - Felesleges keverni a szálkezelést és az async működést: vagy az egyiket használd vagy a másikat, a szabályait betartva! Szálkezelés esetén reszponzív marad az alkalmazás, hiszen a munka másik szálon fut. Async kód használatával ugyanezt elérheted, egyetlen UI szál használatával. De a kettőt keverni nem kéne (pl. az async lambdádban indítasz egy új szálat, ami kilépteti az alkalmazást... rossz nézni is).

    A helyedben async metódusokat használnék szálkezelés helyett.

    - Rengeteg egyéb potenciális hibát látok: Thread.Sleep() egy async metódusban; static tagokat és metódusokat használsz egy többszálú programban szinkronizálás nélkül; megnyitott erőforrások (file-ok) ütközhetnek egymással; az erőforrások nincsenek rendesen Dispose()-olva; direkt indexelsz tömböt, bármiféle hibakezelés nélkül (values[1]), SQL query összeállítása paraméterek nélkül csak így ránézésre. Ezek bármelyike mind-mind dobhat többféle kivételt, amit most kezdesz csak lekezelni, illetve okozhat potenciális hibát most vagy később.

    Szóval átnézendő témák, mielőtt egy ilyen feladatot helyesen el tudnál végezni:

    - tömbök és indexelés
    - kivételkezelés
    szálkezelés (Thread és ThreadPool)
    - async/await használata
    - Dispose() használata unmanaged erőforrások (adatbázis, file stb.) esetén (using blokk)
    - SQL injection elleni védelem: SQL paraméterek használata
    Mutasd a teljes hozzászólást!
  • Valószínűleg az van, amit PolyJoe leírt. Innen kéne szemezgetned: How to: Make Thread-Safe Calls to Windows Forms Controls - a gyakorlatban az InvokeRequired ellenőrzést akár ki is hagyhatod, mert bizonyos mértékig kódduplázással jár, míg az Invoke (pl. Control.Invoke Method (Delegate) (System.Windows.Forms) ) maga akkor is jól működik, ha esetleg épp nem lenne muszáj használni.
    Mutasd a teljes hozzászólást!
  • Szia!
    Köszi a helyreigazítást! A kódból kiszedtem az async/await kódokat, így már maradt egy thread.

    Ami konkrét és nem tud hibával visszatérni az a tömbök indexelése, mert előre generált csv-ből dolgozik a program, ami azt jelenti, hogy az adott tömbindexek fix értékre mutatnak, például a vonalkód a [2] index. Ez fixen fog maradni. Természetesen a többinek utána nézek, mélyebben beleásom magam a témába, hátha sikerül jobban felépítenem!

    Amit sikerült debugolni (kiírattam egy file-ba try-catch kezeléssel:

    System.InvalidOperationException: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.   at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)   at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)   at System.Windows.Forms.Control.Invoke(Delegate method)   at ABCFutar_Sync.SyncWindow.construct() in ***\SyncWindow.cs:line 49

    Emiatt döglik be a kódom.
    Mutasd a teljes hozzászólást!
  • Na, ez konkrét hiba: ez azért lehet, mert a SyncWindow() konstruktorban indítod a szálad, ami már próbál Invoke()-ot hívni az lb_Stat control-ra, az ablak viszont még nem jött létre.

    Próbáld a thread-et a Form.Load eseménykezelőben indítani, addigra már létre kell, hogy jöjjön!
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd