Zastavení běžící procedury   otázka

VB.NET

Dobrý den, používám VB 2010 a potřeboval bych poradit. Mám v aplikaci proceduru, která načte dvě docela rozsáhlé databáze, vzájemně je prohledává a provádí spoustu výpočtů a vyhodnocování. Celá procedura trvá asi dvě minuty (původně jsem to dělal v excelu :) a tam to bylo asi 9 hodin). Nevyužívám klasickou databázi, ale textové soubory, které načítám např. přes "Dim Soubor As New IO.StreamReader(Data)" a po provedení výpočtu je uzavřu.Potřeboval bych poradit:

1. jak např. kliknutím na Button ukončím tuto běžící proceduru

2. jak zároveň s ukončením té procedury uzavřít v ní načtené soubory pokud po ukončení procedury zůstanou načteny

Předem děkuji za radu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

První krok je přesunout procedury do vlastního vlákna (paralelizací úloh lze značně zrychlit celý proces výpočtů a vyhodnocování) a potom lze jednotlivá vlákna ukončit pomocí metody Abort.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Abort je dost násilný způsob a ne vždy 100% funkční. Raději bych to řešil pomocí tasků v .NETu 4, ty podporují rušení ve chvíli, kdy se to té asynchronní úloze hodí.

Ale záleží, jestli má tazatel nové nebo staré Visual Studio.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Vůbec to není násilný způsob, ale zcela korektní postup, který funguje vždy, když se to udělá správně (správně ošetřit ThreadAbortException) a navíc lze to přerušení i odmítnout.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Tak jsem do BackgroundWorker přesunul celou proceduru a mám po problému. Mám totiž aplikaci jako MDIForm a jednotlivé formuláře jako dětičky. Při přepínání mezi jednotlivými dětičkami vždy tu původně otevřenou uzavírám. Můj problém spočíval v tom, že pokud by se někdo rozhodl, že nebude čekat na ukončení výpočtu a přenul se do jiného formuláře, tak to díky uzavírání formuláře s běžícím procesem padalo. Zatím to vypadá, že když mám na formuláři BackgroundWorker a tento formulář uzavřu, tak se ten výpočet automaticky ukončí.Takže ještě jednou děkuji všem za rady.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ale nemůžete říct "tady v tomhle bloku mě nepřerušuj, koukej počkat, než ho dodělám". A to je dost často potřeba.

V C# to řeším přes volatile bool proměnnou, kterou si dávám znamení, že už můžu skončit, anebo přes Task Parallel Library. VB.NET bohužel klíčové slovo volatile nemá a nevím, jestli tohle řešení vůbec je možné, nezkoumal jsem to.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den,všechny náročnější operace by jste měl spouštět ve vlastním vlákně, aby aplikace "nezamrzla". K tomu celkem dobře může posloužit komponenta background worker která má vyřešenou synchronizace a řadu dalších vymožeností. Článek o ní byl myslím na tomto webu a krásná ukázka byla i ve videoturiálech. Dokonce tam bylo vyřešeno i "stornování" procedur běžících ve vlastním vlákně. V podstatě jde o to že backgroundworker má nějakou vlastnost (tuším že to je isCanceled ale to si nejsem jistý) a při práci ve druhém vlákně ji čas od času zkontrolujete. Pokud má pořád hodnotu false je to ok a pokračujete dál, pokud má hodnotu true znamená to že chcete akci stornovat a patřičně na to zareagujete.

Nastavení na true můžete provést třeba z hlavního vlákna právě kliknutím na nějaké tlačítko.

Btw. doporučoval bych použití databáze pokud to je možné, protože hodně věcí je vyřešeno přímo na úrovni databáze a jsou vyřešeny mnohem lépe než jste schopen napsat vy, nebo kdokoli z nás na tomto foru. Pak se může klidně stát, že procedura nepoběží 2 minuty ale 3 sekundy.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Myslím, že by databáze tu proceduru moc neurychlila. Jedna databáze má asi 5500 položek a druhá asi 30000. postupně procházím v první databázi jednu položku za druhou, upravuji je a pak prohledávám druhou databázi, zda se tam vyskytuje. Pokud ano, provedou se určitá porovnání a výpočty a hledám dál. Hlavní problém co se času týče je ale v tom, že ty databáze jsou z různých zdrojů a porovnávané položky nejsou stejně popisovány. Např. v jedné databázi je DN 25 a ve druhé DN 1" nebo v jedné je Karlovo náměstí a ve druhé Karlovo nám. apod. Nejvíce zdržuje právě to, že musím ty položky sjednocovat, aby se daly porovnat.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Děkuji všem za rady, ani jsem nečekal tak bleskové reakce. Já jsem "programátor amatér" a jsem s databázemi po přechodu z VB6 zatím na štíru. Dřív jsem využíval databáze Access. Textové soubory využívám i proto, že si do nich zrovna připíšu i jiné údaje a mám vše v jednom souboru, což mi v některých případech přijde i výhodnější. Co se týče backgroundworker a vlastních vláken, tak to mi zatím taky nic neříká. Jsem ale rád, že aspoň vím kudy na to a jdu o tom něco nastudovat.

Ještě jednou děkuji.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Velmi pěkný popis zde: http://www.albahari.com/threading/

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback