Close formuláře   zodpovězená otázka

VB.NET, Compact Framework

.Net CF 2.0, VS 2008 Pro

Dobrý den

měl bych dotaz v projektu mám spoustu formulářů, jejich instance si vytvořím při načítání projektu. Použití takového formuláře pak volám jen jako xxx.ShowDialog(). A zavření xxx.close().

Nemohu vytvářet instance fomulářů, až před jejich voláním kvůli rychlosti na zařízení.

Při zavolání close se mi některé formuláře "asi" disposují, protože při jejich opětovném volání se mi vyhodí ObjectDisposedException.

Myslel jsem, že musím zavolat na formulář dispose, aby se mi odstranil z paměti.

Je to nějaká chyba ? Věděl by někdo jak formulář zavřít bez dispose ?

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

Na zobrazování formulářů je kód

Form2.Show()
Me.Hide()

Zřejmě myslíte spoustu Dialogových oken.

Vložte sem prosím část kódu, nebo se mrkněte na velice pěkně zpracovaný článek na vytvoření dialogového okna.

http://www.vbnet.cz/clanek--34-vb_net_od...

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

Pozor. Dispose se používá primárně u těch věcí, které využívají nějaké unmanaged zdroje, tedy typicky streamy, různá připojení atd. Pokud používáte pouze modální formuláře, doporučuji je všude používat pomocí Using...End Using a neudržovat je v žádných globálních proměnných. Vyjímka ObjectDisposedException právě znamená, že objekt už byl vyklizen z paměti a tedy není možné používat jeho členy (Close). Formulář se normálně zavírá metodou Close a při garbage kolekci by mělo dojít k zavolání metody Dispose automaticky v destruktoru.

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

Ano using používám u jenoduchych formulářů. Ale mám v aplikaci pár větších,u kterých vytváření instancí na mob. zařízení znatelně zalaguje. Toho jsem se snažil zbavit vytvořením glob. Proměnné které jen výměním nějaké vlastnosti. Formulář zavřu procedurou close, ale u některých se po close, ja to nedělám, formulář disposuje. Jen jsem se ptal jestli na tento problém někdo nenarazil a neporadil si s ním.

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

Nerozumím větě "vytvořením glob. Proměnné které jen výměním nějaké vlastnosti". Doporučuji, abyste si po sobě příspěvky před přidáním několikrát přečetl.

Uvědomte si, že jakmile zavoláte metodu Close, uvolní se tím zdroje držené formulářem a předpokládá se, že s ním dále už nebudete pracovat. Pokud s ním dále pracujete (stačí jen volání některých vlastností nebo metod), je jasné, že dochází k této vyjímce. Radím vám nezavírejte ten formulář pokud to není nezbytně nutné, pouze ho schovejte metodou Hide.

Když už ho zavřete metodou Close, jediné co vám pomůže je přiřadit novou instanci formuláře do původní proměnné.

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

Děkuji za odpověď, myslel jsem, že k uvolnění zdrojů dojde až po zavolaní dispose().

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

No to by bylo dobré, ale mám problém. Mám vytvořenou instanci formuláře, ten někde v programu zavolám ať už Show() nebo ShowDialog() ve formuláři pak dám me.hide(). Co se stane, Formulář se schová, ale zůstane na něm asi fokus protože původní formulář (volající) na nic nereaguje. A tlačítko,které volalo dialog zůstane zamáčknuté.

A moc se mi to s tím close nezdá.

U dalších formů dám v klidu close() a po něm zavolám GarbageCollector , Instance zůstane vytvořená včetně privátních proměnných a mohu bez problému znovu volat Show().

Vyjímka mi vyskakuje jen u jednoho formu(z 6ti které takto provozuji), není v něm nic speciálního proti těm ostatním.

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

No pokud na něm zavoláte ShowDialog tak Vám původní formulář na nic reagovat nebude, protože čeká na zavření toho dialogu (to že dialog není vidět je úplně jedno, podstatné je že je pořád otevřený). Naopak pokud použijete Show a potřebujete vyčkat na vstup uživatele který má něco na tom nově zobrazeném formuláři zadat, tak máte zase smůlu protože kód při show nečeká na zavření formuláře ale jede si dál, takže tudy cesta asi nevede.

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

Problém bude asi v tom, že kreténsky voláte instanční členy jako by byly statické a potom zůstává v paměti bordel. Už se to zde řešilo. Další hovadina kterou děláte, je explicitní volání Garbage Collectoru, které znatelně zpomaluje. Ujišťuji vás, že pokud lze přistupovat ke členům formuláře, na kterém bylo zavoláno Close, je to jen čistá náhoda a může to kdykoliv spadnout. Myslím, že byste si měl zrevidovat svůj prasečí kód a ještě na něj pro jistotu pustit FxCop.

Nezlobte se na mě, ale vy děláte naprosto zásadní chyby, které ovlivňují chování a hlavně výkon celé aplikace.

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

Děkuji za opětovně nádhernou lehce urážlivou odpověď, nicméně GC jsem spouštěl kvůli vaší odpovědi, protože jsem se chtěl přesvědčit, že close vymaže členy instance. To se nestalo.

Sám jako programátor jistě víte, že ne vždy máte k dispozici ideální HW a toto je přesně ten případ, pokud to udělám tak jak se to dělat má. Vytvořením nové instance formuláře, přes using nebo po close použít dispose, tak se aplikace bohužel stane uživatelsky téměř nepoužitelnou.

Dále jsem nechal cca 1 hodinu aplikaci běžet a cyklicky na ní spoštět po 5 minutách GC a ani po hodině nezmizely členové třídy.

Upozorňuji ještě jednou, že jde o CompactFramework 2.0.

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

Nastudujte si konečně něco ohledně Garbage Collectoru a životnosti instancí tříd. Pokud na instanci existuje kdekoliv reference, objekt se z paměti neuklidí (obzvlášť se projevuje u globálních proměnných). Close "nevymaže" žádnou instanci formuláře, pouze uvolní zdroje držené třídou formuláře. Samozřejmě že něco potom ještě může fungovat, ale kdykoliv může dojít k vyjímce. Prostě berte na vědomí, že po zavolání Close se už s tím dál pracovat nemá. Pokud je program napsán korektně, k podobným problémům nedochází. Navíc to absolutně není závislé na hardware, který bývá v dnešní době u mobilních zařízení více než dostačující. Běžně pracuji se zařízeními s 312 MHz CPU a 64 MB RAM a nikdy jsem podobné problémy neměl.

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

Šlo o to, že se na formech vykreslují bitmapy a dále se do nich vykreslují další věci. Když si formulář držel informace o bitmapách tak jeho otevření bylo téměř okamžité. Zatímco když jsem vytvářel instanci a zadával informace o bitmapách a o objektech, které se na ni mají vykreslit tak to trvalo 5 - 10s podle náročnosti. Mám k dispozici jen o trochu lepší zařízení než zde popisujete.

Problém s lagem jsem, alespoň na oko vyřešil otevřením dalšího formu který zobrazuje pouze informace o stavu vytváření instance složitějšího dialogu. Minimálně to vypadá o trochu lépe.

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

Tak to snad můžete přepsat do zvláštní třídy, která se bude starat jen o grafiku a bude nezávislá na formuláři ne?

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

Když to shrnu, máte to prostě celé blbě navržené a udělané. Konkrétní věc vám poradit nemohu, naviděl jsem zdrojový kód.

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

A co zkusit držet v paměti jen tu bitmapu a ne celý formulář? A vždy při vytvoření instance nového formuláře do něj jen plácnout tu hotovou bitmapu. To by nepomohlo? Odpadly by tím všechny ty šaškárny se schováváním formulářů.

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

Takto jsem to měl, tříd bylo něco přes 40 každá v sobě měla 4 bitmapy.

Volba která třída a která bitmapa se bude na formu zobrazovat byla řešena poměrně složitým způsobem v konstruktoru formu. Proto trvalo vytvoření instance o dost déle, než můj předchozí špatný postup.

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

Aha, já měl zato že dlouho trvalo vytvoření bitmapy jako takové.

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

Tak ještě jsem to pro jistotu zkusil v emulátoru a tam to vyhazuje chybu vždy.

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