Anonymní profil Kartmen – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Anonymní profil Kartmen – Programujte.comAnonymní profil Kartmen – Programujte.com

 

Příspěvky odeslané z IP adresy 88.103.206.–

Kartmen
.NET › Formy a vlákna
15. 5. 2021   #387927

1) Jal jsem psal, jde o příklad jak, navíc v MessageBoxem jsem tabulky nikdy nezkoušel vypsat.

2) Psal jsem, že je to něco jako ErrorProvider, což je child okno, kde se vypíše nějaký seznam událostí. Je to komponenta, tedy něco co se dá použít na libovolném místě, není to samotný program, spíš něco co bude v nějaké knihovně, kterou program použije. Nikde jsem nepsal o vytváření formulářů mimo designer, opět jako ErrorProvider, se při použití zadá nějaký control z libovolného UI a v nějakém odstupu od něj se do tohoto UI doplní PictureBox (tento jeden si to tedy vytvoří samo mimo designer), který se v případě, že je v zapsána nějaká událost zobrazí.

Uživatel této třídy (formu) nemusí používat přímo vlákna, klidně může používat pohodlnější tasky.

Neprováděj jsem nějaký sofistikovaný dlouhodobý test, ale za pomocí dvou různých locků to nyní funguje, ale není to moc pěkné, takže řeším jestli to jde líp.

Co je na locku špatného?

Stejně tak co je špatného na těch starých formulářích? Co jsem koukal na zdrojové soubory technologie, které je za mě napsána dost dobře, tedy od základu v C++ pro jednotlivé typy procesorů, s podporou více vláken a až vyšší objekty v C#, tak forms tam mají také ty staré (jen používají dědičnost). Je to soft co pracuje s 3D grafikou, takže spousta komplikovaných výpočtů. Možná to jen vyvíjejí delší dobu (každý měsíc několik updatů) a staré věci se jim nechce přepisovat, kdo ví.

Požití Sleepu mi přijde nesmyslné, tím nejde na nic čekat, nevím přeci jestli operace bude trvat 10ns, nebo 1s, od toho jsem tam ty locky, že to čeká tak dlouho, dokud se neuvolní.

Je to teprve druhá věc co jsem s vlákny kdy dělal a v práci to ani nepotřebuju, spíš zvídavost. Prvně jsem zkoušel obecnou třídu pro výpočty pomocí vláken. Třída má svůj zásobník akcí a postupně je umisťuje podle priorit na vlákna tak, aby byla stále vytížená a tam to invokuje akce ze zásobníku. Co jsem zkoušel udělat pomocí toho pro kontrolu třeba HeapSort, tak to má i na milionech prvků stejný výsledek, jako řazení co je ve frameworku. Požívá to také jen locky a ManualResetEventy

3) Dělam si to složitý, ale bojuju s tím :) Cože oni se prací dají peníze i vydělat, já jim za to ještě platím :)

Co o tom vím, tak system ma svůj ThreadPool, pokud se používají Tasky, tak na to systém použije vlákno odsud, pokud tam není, tak vytvoří nové. Pokud si program vytvoří svá vlákna, tak jsou mimo, ale asi by tam šla dát, nikdy jsem to nepotřeboval. Na počtu vláken moc nezáleží, běžně ve windows běží mnohem větší počet vláken než kolik vláken má procesor a systém si sám řídí, jaké vlákno kdy obslouží, částečně to jde snad ovlivnit nastavenou prioritou vlákna. Pro jistotu jsem ale dělal o jedno vlákno méně než kolik jich procesor má.

Kartmen
.NET › Formy a vlákna
15. 5. 2021   #387923

#5 JerryM

Jak jsem psal, tak já WPF používal, ale ve firmě se nepoužívá, proto jsem se ptal v čem jsou ostatní novější věci lepší, já v tom moc rozdíl nevidím. Dotaz byl tedy spíš na ty rozdíly než na vlákna, třeba se mi pak WPF podaří spíš protlačit...

Dotaz ohledně DataGridViewu jako Excel se pokusím namalovat.

Připojen obrázek.

Pokud nerozumíš původnímu dotazu, tak jo nenapsal jsem to moc detailně, jestli že to snad někdo, kdo se s tím setkal pochopí, ale klidně to víc rozepíšu, jen aby pak zase někdo četl dlouhý text.

Kartmen
.NET › Formy a vlákna
15. 5. 2021   #387922

#3 gna
Radši jsem dal i ten konstruktor na vlákno UI. Přišlo mi, že když to tak nebylo, tak se děly divné věci, jako třeba form.InvokeRequired hlásil false i pro jiná vlákna než bylo to UI. Taky mě vrtá v hlavě, jaký je asi rozdíl v podmínkách 

if (this.InvokeRequired) //this je form
  this.Invoke(...);

vs

if (_vlaknoUI != Thread.CurrentThread.ManagedThreadId) //_vlaknoUI je v konstruktoru formu zapsane ID
  this.Invoke(...);

S tou frontou by byla práce navíc, ale teoreticky by se neblokovala vlákna a mohla pokračovat v práci minimálně do zahlcení fronty.

Jak teď s vláknama začínam, tak hledam nějaký vzor, nebo šablonu, jak to do budoucna dělat a pokud možnost, aby to nepřidávalo kódu navíc, šlo se v tom vyznat a fungovalo to. Aktuálně dělam něco jako ErrorProvider jen trochu lépe nastavitelný než je v těch starých formulářích. Tedy libovolné vlákno může poslat info o události a můj form ji zobrazí, přičemž vše kromě samotného Invoku třeba se zápisem do TextBoxu se děje na jiném vláknu a ostatní vlákna musí čekat než se předchozí akce dokončí.

 Příklady akcí, které běží na libovolném vláknu, které pouze pro zápis do controlů používají invoke a aby se nemíchaly invoky různých akcí, tak je tam lock. Fungovalo by to bez locků, pokud by se invokovali rovnou celé ty metody, ale pak to byl jednovláknový program. 

    private void AkceZapisText(List<string> text)
    {
      lock (_akceLock) //dokud neprobehne cely cyklus, tak nesmi zacit jina akce
      {
        foreach (var item in text)
        {
          //...
          Form.Invoke(delegateZapisDoTextboxu, item); //logika okolo je v nejakem vlaknu, jen samotny zapis se invokuje
          //...
        }
      }
    }

    private void AkceSeradSeznam()
    {
      lock (_akceLock) //dokud neprobehne cely cyklus, tak nesmi zacit jina akce
      {
        Form.Invoke(delegateOdstranZapsane); //stavajici seznam odstrani
        List<string> razene = _seznam.Sort(); //nejake serazeni dat
        foreach (var item in razene) //zapis serazeneho seznamu
        {
          //...
          Form.Invoke(delegateZapisDoTextboxu, item); //logika okolo je v nejakem vlaknu, jen samotny zapis se invokuje
          //...
        }
      }
    }
Kartmen
.NET › Formy a vlákna
13. 5. 2021   #387895

Po nějakém čase zase velký problém.. Pokouším se napsat Form, který by fungoval i v případě přístup z více vláken. Nevím určitě, ale asi je nutné vytvářet všechny Controly přímo ve vlákně kde vznikl Form, tedy konstruktory musí být ve stejném vlákně? Nebo stačí do formu control jen zapsat (Controls.Add) ve stejném vláknu, ale může vzniknout i mimo?

Další problém ale je když vlákna něco odešlou... Jestli jen pomocí locku zajistit, aby probíhala jen jedna akce a posílat Invokem do hlavního vlákna UI to co mění data controlů, nebo radši udělat nějaký zásobník, kam se všechny akce budou zapisovat a Invokovat je až ze zásobníku.

Nejhorší mi přejde ukončení, kdy se něco může právě invokovat, další vlákna čekají na dokončení a přednostně chci všechny akce (tu co probíhá i ty čekající) ukončit a provést ukončení (zavření formu). Problémem tu je, že v hlavním vlákně UI nelze použít žádný lock, nebo jiný způsob čekání na dokončení (ukončení) probíhající akce, protože na tomto vlákně probíhají invoky, což by vedlo deadlocku. Řešil jsem to tak, že jsem ukončení spustil na jiném vlákně a tak čeká na lock, jako ostatní vlákna a jejich akce, které mají signalizováno předčasné ukončení... ale nepřijde mi to moc pěkné, tak jestli není nějaké lepší řešení.

Kartmen
.NET › Knihovna jen z v aktuálním p…
2. 10. 2020   #386731

Ještě jeden důvod mě napadá, občas se stává, že se zákazníkovi dává i zdrojový kód.

Díky za pomoc.

Kartmen
.NET › Knihovna jen z v aktuálním p…
2. 10. 2020   #386726

#5 hlucheucho
To ruční přidávání už dá práci a co teprve řešit nějaké chainy, kdy třída závisí na jiných a ty na jiných... a ani celé třídy nebudou většinou použité. Pokud mají spoustu metod a všeho možného, tak se při použití třídy využívá jen něco málo.

Ber to jako filozofickou otázku, ale začal jsem to řešit, protože mam svou knihovnu, která stále roste a přitom z ní často používam jen zlomek. Jasně šla by rozložit na několik souborů a to už zase není tak pohodlné, stále přemýšlet co je v jaké knihovně. O místo až tak nejde, i když je trochu prasárna z programu co může mít 1MB udělat 100 jen proto, že tam připlácnu spoustu knihoven.

Něco takového by také bylo řešení, aby si sám kompilátor vytahnul jen co potřebuje.

Kartmen
.NET › Knihovna jen z v aktuálním p…
2. 10. 2020   #386720

#2 JerryM
Mam jeden velký hotový projekt, ve kterém je dejme tomu několik tisíc tříd.

Pak mam druhý projekt, na které aktuálně dělam a občas nějakou třídu, metodu, nebo cokoliv z toho velkého projektu použiju a chtěl bych, aby to z toho velkého projektu vycuclo všechen kód, který je nezbytný a jen z toho kódu aby to udělalo knihovnu. Ten druhý, pracovní projekt je něco co se stále mění, podle toho na čem právě dělám, takže pokaždé použiju z velkého projektu jiné části. Normální je udělat z velkého projektu knihovnu, která bude mít několik mega a neřešit, že aktuálně jsem z ní použil 10 řádků kódu. Já se ptam, jestli existuje něco, co by na základě použití dokázalo udělat knihovnu jen z těch 10 řádků.

Kartmen
.NET › Knihovna jen z v aktuálním p…
30. 9. 2020   #386711

Ahoj, je to asi dotaz spíš na Visual studio. Nevíte jestli existuje typ projektu, nebo nějaký způsob, jak by šlo používat něco jako referenční projekt, ze kterého by se po použití nějaké jeho části v "normálním" projektu automaticky překopírovalo vše co je potřeba do projektu, na kterém právě dělám? Něco čím bych se vyhnul ručnímu kopírování, nebo naopak zbytečné používání knihovny, ze které je použito pár řádků kódu. Nebo kdyby šlo vytvořit knihovnu, kde bude jen to co se v projektu opravdu používá.

Kartmen
MS SQL › Import co nejrychleji
22. 9. 2020   #386658

Úplně to nesouvisí s tou databází, ale když měřím čas průběhu přes System.Diagnostics.Stopwatch, který spustím před metodou importu a stopnu to za ní, tak to ukazuje, že ta metoda zabere 30% času. Zatímco Performance profiler CPU, ukazuje že ta metoda má 80% vytížení. Takže mezi tím úplně vztah asi není co? Ta metoda asi jen víc vytěžuje procesor (procesory).

Kartmen
MS SQL › Import co nejrychleji
19. 9. 2020   #386652

Ano začínam, ale jak jsem psal, vycházím z existujícího kódu, který snad můžu jen zlepšit, respektive pokud to bude ještě pomalejší, tak můžu nechat ten původní. Vstupní soubor což je export z nějaké databáze, je členěn do těch 100 tabulek. Do toho jak mají vytvořenou tu databázi nevidím, interně to může být mnohem víc tabulek. Evidentně to nikdo moc neřešil a rovnou z toho udělal jednu tabulku, takže normalizováno to není vůbec. Musím zjistit jaká je návaznost dalších programů, které s importovanou databází pracují, ale nejspíš budou vyžadovat buď ty původní kompletní tabulky, nebo předělat kód pokud bych to rozdělil (a nevytvořil z nich opět tu původní). To jestli bude interně databáze přehlednější tedy možná nikdo (uživatel) ani nepostřehne pokud k ní přistupuje přes nějaký program a jeho UI, ale to jestli se to bude importovat 5 minut, nebo hodinu ano.

Kartmen
MS SQL › Import co nejrychleji
19. 9. 2020   #386648

Jasný a databáze bude asi i o dost menší. Má to asi 100 tabulek, které mají tak 20-50 sloupců.

Kartmen
MS SQL › Import co nejrychleji
19. 9. 2020   #386646

Už to asi chápu, rozložit velkou tabulku na několik menších?

Kartmen
MS SQL › Import co nejrychleji
19. 9. 2020   #386645

Být to v mém kódu, tak bych asi zkusil udělat hash všech sloupců a až při shodě hashe testovat na shodnost jednotlivé sloupce. V databázi nevim, ale možná to přesně tak dělá.

Kartmen
MS SQL › Import co nejrychleji
19. 9. 2020   #386644

#19 Kit
Já to nevymýšlel, jen se to snažím přepsat, aby to fungovalo trochu rychleji. Jak by to šlo vyřešit lépe? Mě napadlo, že zkusím ty sloupce klíče aspoň přeházet, aby byl pokud možno první ten (ty), ve kterých je největší šance, že se budou lišit. Další sloupce se pak už snad ani nebudou testovat.

Kartmen
MS SQL › Import co nejrychleji
19. 9. 2020   #386641

Po pár testech bych řek, že je pomalost dána složitostí databáze. Některé unikátní klíče tvoří 6 a asi i více sloupců. Na začátku to běží rychle, ale jak se přidávají data a testuje se unikátnost, tak to zpomaluje.

Pár dotazů:

1) Je lepší narvat co nejrychleji data do databáze a až je v ní vše, tak teprve otestovat unikátnost, nebo to dělat v průběhu, nebo je to jedno a trvá to vždy cca stejnou dobu?

2) Nastavení tabulky je stejné pro všechna připojení, nebo by šlo, aby jednotlivá připojení měla různé třeba defaultní hodnoty sloupců?

Kartmen
MS SQL › Import co nejrychleji
2. 9. 2020   #386557

Jaké optimalizace myslíš? Napadá mě jen zapnout optimalizace v nastavení projektu VS, což nemá žádný vliv, protože v naprosté většině kód běží v externí části (knihovna frameworku kde je SqlBulkCopy). Pak snad jedině přepsat tu knihovnu.

Padlo tu, že by import měl jít prakticky rychlostí čtení... a na to, že se v mém případě už jen čte z paměti a zapisuje do databáze, tak je to teď cca 3MB/s (pokud počítám plnou velikost řádku databáze, řada sloupců je null, nebo jsou texty výrazně kratší než je limit, takže ze zdroje jde cca 1,5MB/s).

Kartmen
MS SQL › Import co nejrychleji
1. 9. 2020   #386551

Asi by taky šlo kontrolu spustit až nakonec, ale přijde mi jestli to není zbytečně složitější, i když to bude databáze na počítači, na kterém je spuštěný program, tak se to nejprve importuje a pak zase exportuje, přijde mi to jako krok navíc a pokaždé se to musí parsovat mezi C# typy a SQL.

Rozdělit to jde, jen je to trochu složitější. Právě jsem zjišťoval jsem jestli to má cenu, jestli je to opravdu rychlejší, když to běží ve více vláknech, protože mi pár lidí tvrdilo že ne. Každopádně to otestuju.

Nevím jak otestovat jestli těch cca 8000 řádků/s je normál, nebo je to bída. Možná je problém v nějakém nastavení databáze.

Kartmen
MS SQL › Import co nejrychleji
1. 9. 2020   #386541

To co jsem posílal bylo bez kontrol (jsou vypnuté), jediné co se tam děje je parsovaní ze stringu. Co jsem testoval, tak to jestli pošlu sql typy, nebo string a ať si to naparsuje databáze, tak překvapivě vyšlo prakticky na stejno.

Drtivá většina testů nesouvisí s tím jestli to proleze do databáze, nebo ne. Třeba řetězec, pokud má správnou délku proleze vždy, ale měl by "dávat smysl", ve výsledku se do databáze často stejně pošle, ale zaloguje se podezřelá hodnota.

Kartmen
MS SQL › Import co nejrychleji
1. 9. 2020   #386539

Vložení prvních 100 000 řádků jako je ten níže do tabulky na mém core i7-4790 3.6GHz trvá 13s, je to odpovídající?

      //object[] _data 
      _data[0] = SqlDecimal.Parse("12345678901"); //9x numeric
      _data[1] = SqlDecimal.Parse("12345678901"); 
      _data[2] = SqlDecimal.Parse("12345678901"); 
      _data[3] = SqlDecimal.Parse("12345678901"); 
      _data[4] = SqlDecimal.Parse("12345678901");
      _data[5] = SqlDecimal.Parse("12345678901");
      _data[6] = SqlDecimal.Parse("12345678901");
      _data[7] = SqlDecimal.Parse("12345678901");
      _data[8] = SqlDecimal.Parse("12345678901");
      _data[9] = SqlDecimal.Parse("12345678901"); 
      _data[10] = SqlDateTime.Parse("2014.12.11 06:32:38"); //2x datatime
      _data[11] = SqlDateTime.Parse("2014.12.11 06:32:38");
      _data[12] = SqlInt16.Parse("0"); //11x smallint
      _data[13] = SqlInt16.Parse("0"); //unikatni 0
      _data[14] = SqlInt16.Parse("0"); //unikatni 0
      _data[15] = SqlInt16.Parse("0"); //unikatni 0
      _data[16] = SqlInt16.Parse("0"); 
      _data[17] = SqlInt16.Parse("0"); 
      _data[18] = SqlInt16.Parse("0"); 
      _data[19] = SqlInt16.Parse("0"); 
      _data[20] = SqlInt16.Parse("0"); 
      _data[21] = SqlInt16.Parse("0"); 
      _data[22] = SqlInt16.Parse("0");
      _data[23] = SqlInt32.Parse("123456"); //4x int
      _data[24] = SqlInt32.Parse("123456"); 
      _data[25] = SqlInt32.Parse("123456"); 
      _data[26] = SqlInt32.Parse("123456"); 
      _data[27] = new SqlChars("x"); //5x nvarchar, delka 10 
      _data[28] = new SqlChars("x"); //delka 100
      _data[27] = new SqlChars("x"); //delka 1
      _data[29] = new SqlChars("x"); //delka 1
      _data[30] = new SqlChars("x"); //delka 1
Kartmen
MS SQL › Import co nejrychleji
31. 8. 2020   #386537

#6 Kit
To jsem nepobral můžeš to trochu rozvést?

Kartmen
MS SQL › Import co nejrychleji
31. 8. 2020   #386533

Myslel jsem, že to stačí obecně, jestli je paralelní import rychlejší a následně to používat na libovolné databáze. Třeba teď mam nějaké, které mají od 100MB, průměr je asi pár giga, ale jsou i terabytové. Struktura je celkem jednoduchá, ale ve všem může být chyba, takže se to před importem testuje, jestli je číslo číslo, datum jestli dává smysl atd, ale to bych neřešil to se provede v jiném vlákně. Výsledek zatím podle CPU profileru VS je, že 80% času trvá externí kód třídy SqlBulkCopy metody WriteToServer pomocí datareaderu. 

Kartmen
MS SQL › Import co nejrychleji
29. 8. 2020   #386531

Omezení hard diskem tu bude, ale i tak je v nastavení řada parametrů, které to nejspíš mohou ovlivnit a které potřebuji nějak optimálně nastavit. Třeba zápis na disk nevím jestli databáze musí nutně dělat v reálném čase, pokud má počítač dost paměti (víc paměti než jak je velká databáze), tak by teoreticky nemusela. Nicméně z disku se načítá soubor s daty, která se do databáze zapisují. Pokud bych načetl databázi rychlostí čtení z disku, tak by mi to pro začátek stačilo :)

Kartmen
MS SQL › Import co nejrychleji
28. 8. 2020   #386529

Ahoj, chtěl bych se zeptat jak co nejrychleji načítat opravdu velké databáze. Moje představa byla, že pro zápis do databáze využiju všechna vlákna procesoru, ale co jsem se z několika zdrojů doslechl, tak to nemá moc cenu a ani to nemusí být rychlejší... je to opravdu pravda? Liší se nějak jednotlivé databáze MS SQL, MySQL, PostgreSQL a další v možnostech urychlení importu? Nebo je pro urychlení lepší zapisovat do několika instancí databáze, protože na současný zápis z více vláken nejsou dělané?

Kartmen
.NET › návrh třídy
17. 8. 2020   #386447

#2 Kit
To byl jen příklad, respektive ona ho klidně může jen načítat, ale nějak se parsuje vstupní formát a nějak se z dat vytváří objekty, nebo se to jen zapíše do databáze. Jde spíš o to, jestli třída určená k jedinému účelu, má (může) to co dělá udělat hned v konstruktoru, nebo jestli má mít spíš nějakou metodu, které to spustí, nebo je to jedno. 

  public class ImportDat
  {
    internal readonly string _nazevSouboru;
    //rada readonly promennych tridy
    //...
    //...
    //...

    public ImportDat(string nazevSouboru)
    {
      _nazevSouboru = nazevSouboru;
      //... treba i delsi kod importu

    }

  }

Vše v konstruktoru, respektive i z něj volám jednotlivé metody, ale už je to delší... Výhody jsou, že vnitřní proměnné třídy mohou použít atribut readonly a kdo bude třídu používat, tak jen vytvoří objekt, nemusí už hledat jakou metodou to ještě spustit.

  public class ImportDat2
  {
    internal readonly string _nazevSouboru;
    //rada promennych tridy
    //...
    //...
    //...

    public ImportDat2(string nazevSouboru)
    {
      _nazevSouboru = nazevSouboru;
    }

    public void Spust()
    {
      //... kod importu
    }

  }

Nebo je čistější udělat maximálně jednoduchý konstruktor a delší kód mít až v metodě, která se musí extra volat?

Kartmen
.NET › návrh třídy
17. 8. 2020   #386444

Ahoj, mam dotaz na to jestli existují nějaké zásady, ohledně psaní tříd. Sice je to možná obecnější než jen Net, ale používam teď hlavně ten. Uvítám libovolné postřehy, ale aktuálně mi jde o hlavně o toto. Je špatné, vytvářet složitější konstruktory, spíš než to co třída děla rozložit do metod? Mam například třídu, která dostane nějaké nastavení, kde je např. jen cestu ke zpracovávanému souboru. Je lepší udělat konstruktor, který jen přebere nastavení a pro zpracování souboru je následně nutné zavolat nějakou metodu např. Start? Nebo udělat konstruktor, který přebere nastavení a rovnou zpracuje soubor? Třída samotná jen načítá soubor, nic jiného nedělá.

Kartmen
.NET › Nový C# 9.0 :) pro všechny…
4. 8. 2020   #386422
Kartmen
.NET › Nový C# 9.0 :) pro všechny…
4. 8. 2020   #386419

Je tam něco zásadního bez čeho se člověk neobejde, nebo to aspoň znatelně zrychlí práci? Video mi nejde, asi to v práci blokujou:(

Kartmen
.NET › Vlákna, jak je ukončit
6. 3. 2020   #385600

Ok. Ještě menší dotaz na Visual Studio, neznáte někdo dobrý způsob (Addon), na ladění více vláken, kdy chci sledovat jen jedno, nebo několik vybraných vláken a ostatní ne? Zatím jsem vygoogloval jen nic moc řešení, kdy se dají breakepointy na každý řádek a nastaví se podmínka na thread, který chci ladit. 

Kartmen
.NET › Vlákna, jak je ukončit
5. 3. 2020   #385590

Ahoj, chci si zeptat, jestli existuje nějaká dobrá možnost jak ukončit nejlépe jen proceduru (ne vlákno), která již není potřeba. Mam třeba 10 vláken, které počítají to samé jiným způsobem, když nejrychlejší vlákno spočte výsledek, tak ostatní již není potřeba dopočítávat... Nejradši bych chtěl ukončit jen aktuálně spuštěné akce na vláknech a nahradit je jinými, podobně jako když se vlákno nějakou metodou spustí. Nebo to nelze a je nutné, aby časově náročná procedura sama testovala, jestli se nemá ukončit? Nebo použit nic moc řešení a Thread.Abort() a udělat si vlákno jiné?

Kartik
Visual Basic › jde ve VBA přímo uvolnit pam…
11. 10. 2018   #381901

Tam ale vidím jen rušení celých objektu, jsem chtěl vědět jestli je možné zrušit jen část objektu, nebo část pole. Respektive jak v těchto případech pracuje garbage collector, např. když vytvořím pole2, jehož data nasměruju na objekt, nebo data jiného pole, tak jestli se při rušení tohoto pole2 opravdu uvolní paměť, nebo jestli si to pohlídá, že stejnou paměť používá ještě něco dalšího.

Kartik
Visual Basic › jde ve VBA přímo uvolnit pam…
10. 10. 2018   #381895

Snažím se udělat funkci, která dostane jako parametry Ukazatel a Size a mela by uvolnit paměť v tomto rozsahu. Chtěl jsem to udělat tak, že vytvořím pole typu Byte správné velikosti a jako ukazatel na data dam parametr Ukazatel. Takže jen prohodím ve struktuře safeArray ukazatel na data. Plán je takový, že jakmile dojde na rušení funkce, ve které je toto pole, tak to uvolní paměť, kterou potřebuju... ale nějak to nefunguje.

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function VarPtrArray Lib "VBE6" Alias "VarPtr" (var() As Any) As Long 

Private Sub test1()

Dim arr() as long
dim nula as long
dim ptr as long

redim arr(10)
...
ptr=VarPtr(arr(8))
CopyMemory Byval VarPtrArray(arr()),nula,4 'pole má nyní ukazatel 0, takže ho VBA nejspíš samo nedealokuje
test2 ptr, 12

end sub

Private Sub test2(ptr as long, size as long)
'tady chci uvolnit paměť, jestli je to nějak možné

dim delArr() as byte
dim arrPtr as long

redim delArr(size-1)
CopyMemory arrPtr, Byval VarPtrArray(delArr()), 4 'ukazatel na strukturu safeArray
CopyMemory Byval arrPtr+12, ptr, 4 'změna ukazatele na data
'a teď by se teoreticky měla po ukončení funkce paměť pole uvolnit... ale nevim jak přesně funguje garbage collector, jestli paměť neuvolní hned, nebo ji to uvolní ale hodnoty tam zůstanou nebo ?

end sub

 

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032022 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý