Třídy a funkce .NET frameworku, o kterých je dobré vědět

16. díl - Třídy a funkce .NET frameworku, o kterých je dobré vědět

Tomáš Herceg       31.12.2007       C#, VB.NET, .NET       21271 zobrazení

Mnoho začátečníků ani středně pokročilých netuší o velice užitečných funkcích, které jsou sice jednoduché, ale značně zrychlí, usnadní a zpřehlední vývoj aplikací. V tomto článku se podíváme na některé funkce ze System.IO, dále pak na formátování data a času, kolekce a generické seznamy a StringBuilder.

Naučit se nějaký programovací jazyk, třeba Visual Basic .NET či C#, je snadné. Daleko větším problémem bývá ale často naučit se obrovskou škálu funkcí, které nám .NET Framework poskytuje. Znám spoustu vývojářů, kteří přejdou na C# a za týden v něm prý umí programovat, je to přece tak snadné. Ale otrocky píší funkce, které už .NET má naimplementované. Navíc, když si vše píší sami, nepokryjí třeba všechny případy, které mohou nastat, a pak se diví, když jim kód nedělá, co má.

Právě proto jsem se rozhodl napsat tento článek - jedna věc je znát jazyk a druhá věc je znát funkce a třídy .NET frameworku tak, abychom jej efektivně využívali a nepsali znovu to, co napsal někdo jiný a v mnoha případech ještě k tomu lépe. V tomto článku tedy najdete několik užitečných funkcí, které mě zrovna napadly. Tento seznam není rozhodně úplný, pokud budete mít nějaké nápady, co přidat, určitě napište do diskuse, ať můžu udělat pokračování článku. Budu se snažit také poukázat na některé chyby, které začátečníci obvykle dělají.

Zápis a čtení textových souborů

StreamReader a StreamWriter jsou dvě velmi často používané třídy, které čtou, resp. zapisují z/do textového souboru. Známe je skoro všichni, StreamReader má metody ReadLine a Read, první z nich přečte jeden řádek v souboru a druhá umí načíst ze souboru zvolený počet znaků (typ Char). StreamWriter má medoty WriteLine a Write, první z nich zapíše do souboru řádek textu a druhá má spoustu různých přetížení, takže umí do souboru zapsat čísla, pole znaků, datum atd. Velmi důležité je při ukončení práce se souborem zavolat Close. Pokud jej nezavoláme při čtení souboru, tak se toho zase tolik nestane, až na to, že soubor bude nepřístupný, dokud je aplikace spuštěná. Pokud jej ale nezavoláme při zápisu do souboru, mohou se dít zajímavé věci. Zavolání Write a WriteLine totiž nezapisuje římo na disk, ale do paměťového bufferu, který se ukládá až když je toho více. To vše se děje kvůli vyššímu výkonu, zapsání dat na disk je poměrně pomalé. Pokud vám ale aplikace spadne, může se stát, že i když do souboru již delší dobu nezapisujete, data jsou stále ještě v paměti a ne na disku.

Na těchto dvou třídách je zajímavý ještě jeden detail, a to volba kódování národních abeced. Kdyby Jan Hus kritizoval raději jen církev a nešťoural se i v jazyce českém, měli bychom o dost lehčí život. Ale vzhledem k tomu, že počítače vznikaly převážně v zemích, kde podobná individua nepůsobila, na háčky a čárky se tak nějak zapomnělo. Proto dnes máme několik různých kódování - Windows 1250, ISO 8859-2 a UTF8. Vřele doporučuji vždy a všude používat kódování UTF8, protože podporuje téměř všechny možné i nemožné znaky na světě. Abychom měli jistotu, že se bude ukládat a načítat v kódování, které opravdu chceme, je dobré jej nastavit při vytváření objektů.

Dim sw As New IO.StreamWriter("c:\soubor.txt", False, System.Text.Encoding.UTF8)

Při vytváření StreamReaderu lze nastavit, že si má objekt vyvěštit použité kódování sám. Můžeme ale kódování nastavit napevno sami, pokud máme jistotu, že dostaneme soubory jen v tomto kódování.

Načtení a zápis do souboru na jeden řádek

Pokud potřebujeme provést nějakou jednoduchou operaci se souborem, jako třeba načíst jej celý do proměnné, nebo naopak Stringovou proměnnou uložit do souboru, stačí nám na to funkce ReadAllText a WriteAllText. Mají dokonce i ekvivalenty pro pole bajtů, a to ReadAllBytes a WriteAllBytes. Použití je jednoduché:

Dim text As String = IO.File.ReadAllText("c:\soubor.txt")
IO.File.WriteAllText(
"c:\soubor.txt", text.ToUpper())

Hodí se často ještě funkce ReadAllLines, která načte textový soubor a vrátí pole Stringů, kde každá položka pole je jeden řádek v tomto souboru. Jen dejte pozor, abyste nenačítali příliš velké soubory přímo do paměti, pokud je velikost souboru v řádech megabajtů, použití těchto funkcí již většinou není na místě!

Práce s cestami

Velmi zajímavá je třída System.IO.Path. Ta obsahuje spoustu funkcí pro práci s cestou, které si spousta lidí často píše sama. Proč se ale namáhat? Většinu funkcí pro práci s cestou k souboru již máme připravenou.

Sloučení dvou částí cesty je operace velice častá, na to máme funkci Combine. Nemusíme tedy dávat pozor, aby první část končila nebo druhá začínala lomítkem, díky čemuž by se cesta složila špatně. Použití funkce Combine je snadné:

Dim cesta As String = IO.Path.Combine(Application.StartupPath, "templates\sablona.xml")

Občas potřebujeme z cesty vytáhnout pouze jméno souboru. Ano, šlo by to napsat velmi jednoduše pomocí metody Substring a LastIndexOf (stačí najít poslední lomítko v řetězci a vzít jen část za ním). Ale osobně preferuji způsob, který "říká, co se děje", a ne nějakou práci se Stringem. Navíc pokud vám někdo do adresy napíše místo zpětných lomítek lomítko obyčejné, už je to problém. Máme na to přece funkci GetFileName.

Dim nazev As String = IO.Path.GetFileName(cesta)

Velmi podobná je funkce GetFileNameWithoutExtension, která také vrátí jméno souboru, ale bez přípony. A ještě často používám funkci GetDirectoryName, která vrátí cestu k adresáři, ve kterém se nachází daný soubor. Je to vlastně opačná funkce k GetFileName - GetFileName odřízne cestu a nechá jen název souboru, GetDirectoryName odřízne název souboru a nechá jen cestu k jeho rodičovskému adresáři.

Potřebuji dočasný soubor

Občas vaše aplikace potřebuje dočasný soubor pro uložení něčeho. Jednoduché, vygenerujete náhodně nějaký název a uložíte. A jako na potvoru si přepíšete jiný dočasný soubor, takže musíte přidat ještě kontrolu, jestli takový soubor s náhodným názvem již neexistuje. Ale to už zase není na jeden řádek. Proto je rychlejší a lepší použít funkci GetTempFileName z naší třídy System.IO.Path.

Dim tempFilePath As String = IO.Path.GetTempFileName()

Pokud použijete tuto funkci, máte jistotu, že do daného souboru budete mít práva zápisu a tento soubor bude také uložen v adresáři, který je na to určen, a ne někde v Program Files, kam slušné aplikace nikdy nezapisují, pokud to nejsou instalátory.

Cesty ke speciálním složkám ve Windows

Poslední podkapitolou týkající se souborového systému jsou cesty ke speciálním složkám, jako např. Application Data, Dokumenty, Temp, Obrázky, Videa, Program Files atd. Téměř v každé verzi Windows jsou tyto cesty maličko jinačí. Rozhodně nikdy nevypisujte tyto cesty natvrdo, já osobně si třeba téměř všechny tyto cesty měním - na disku C: mám jen Windows a Program Files, ale Dokumenty a všechno ostatní mám na disku D. Když jednou za rok přeinstalovávám, nemusím nic zálohovat, nemusím hledat, kde jsem ještě co zapomněl. Občas se ale objeví (zejména starší) aplikace, která má někde cestu uvedenou pevně a neptá se systému, kde že má dokumenty. Aby se nám tohle nestávalo, máme na to funkci Environment.GetFolderPath, které jako parametr předáme, jakouže to cestu chceme. Vše se nám ukáže v kontextové nabídce IntelliSense, stačí si jen vybrat. Takto třeba získáme cestu ke složce Obrázky.

Dim obrazky As String = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)

Je libo něco změřit?

Občas se vyskytne potřeba změřit, jak dlouho něco trvá. Asi nejjednodušší je použít funkci Environment.TickCount, která vrací počet milisekund od startu systému. Na extra přesné měření rozhodně nění, má přesnost asi 15-20ms, ale na běžné použití bohatě dostačuje.

        Dim start As Long = Environment.TickCount
'... nějaká časově náročnější operace
MsgBox(Environment.TickCount - start)

Spojování Stringů

Potřebujete poskládat nějaký delší text ze spousty textů menších? Tak na to pozor, pokud nepoužijete StringBuilder, můžete proces velice zpomalit. Pokud totiž napíšu a &= "abc", protože chci za to, co už v a je připojit text "abc", vytvoří se v paměti nová proměnná, zkopíruje se do ní původní obsah a a přidají se za ni nová 3 písmenka. Stará proměnná a se zahodí. To je náročné nejen paměťově (takto zaplácanou paměť je potřeba odstranit), tak i časově, zbytečně kopírujeme tuny textu kvůli přidání 3 písmenek. A právě proto zde máme třídu StringBuilder, která to udělá tak, jak bychom čekali. Jen tak pro zajímavost, obyčejné spojování Stringů v první ukázce trvalo něco přes 25 sekund, zatímco při použití StringBuilderu byl čas neměřitelný (ukázalo se 0ms, přesnost měření ale byla asi 20ms, používal jsem TickCount). Rozdíl je tedy opravdu dramatický.

        'takhle určitě NE!
Dim t As String = ""
For i As Integer = 1 To 50000
t &=
"abcdefg"
Next



'takhle už ano
Dim sb As New System.Text.StringBuilder()
For i As Integer = 1 To 50000
sb.Append(
"abcdefg")
Next
Dim t As String = sb.ToString()

Na druhou stranu, pokud skládáte deset krátkých slov, pak je použití StringBuilderu spíš pomalejší, vytvoření objektu a volání ToString, abychom získali finální řetězec, totiž něco stojí. Pokud ale slučujete delší texty nebo velký počet textů, pak není co řešit.

Převod Stringu na bajty a opačně

Často potřebujeme text převést na pole bajtů, protože jej potřebujeme např. zašifrovat nebo poslat po síti. Šifrovací a síťové funkce pracují s poli bajtů, proto musíme mít funkce pro převod hodnoty String na pole bajtů. Není to až tak triviální, protože do 1 bajtu můžeme uložit pouze 256 různých čísel, zatímco písmenek máme daleko více. Znaková sada Unicode jich čítá přes 100 000, z toho tedy logicky plyne, že některé znaky musí zabírat více než 1 bajt. Pro převod tedy máme funkce GetBytes a GetString, které najdeme u třídy s kódováním, které chceme použít. Pokud tedy kódujeme ve Windows 1250, použijeme System.Text.Encoding.Default.GetBytes, pokud chceme UTF-8, pak použijeme System.Text.Encoding.UTF8.GetBytes atd. Příklad je zde:

        Dim text As String = "Příliš žluťoučký kůň úpěl ďábelské ódy."
Dim bajty() As Byte = System.Text.Encoding.UTF8.GetBytes(text) 'převést text na bajty
Dim text2 As String = System.Text.Encoding.UTF8.GetString(bajty) 'získat text zpátky

Formátování textu, data a čísel

V mnoha aplikacích potřebujeme nějak přehledně zobrazit určité údaje, jako např. datum, čas anebo nějakou částku. Protože různé národy mají různě šílené zvyklosti pro zapisování data, času, měny a čísel, .NET framework obsahuje robustní část věnovanou právě lokálním zvyklostem a nastavení. To je ale téma na samostatný článek, spíše bych chtěl ukázat formátovací funkce, které se velmi často hodí.

Jistě mi dáte za pravdu, že první zápis v MsgBoxu není tak přehledný jako ten druhý, a přitom oba dva udělají skoro to samé:

        Dim castka As Decimal = 134.5
Dim zacatek As Date = #1/1/2007#
Dim konec As Date = #3/31/2007#

MsgBox(
"Za období '" & zacatek & "' - '" & konec & "' máte přeplatek " & castka & " Kč.")
MsgBox(
String.Format("Za období '{0}' - '{1}' máte přeplatek {2:c}.", zacatek, konec, castka))

V prvním MsgBoxu poskládáme větu s daty a částkou. Přes všechno skládání jablek a hrušek do sebe zaniká pravá podstata toho, co chceme udělat. Kdybychom třeba chtěli aplikaci lokalizovat do jiného jazyka s jiným slovosledem, asi by se nám to dělalo hodně těžko. Daleko jednodušší je použít funkci String.Format, které řekneme, kam se má do věty co dosadit. Texty pro lokalizaci můžeme mít uloženy úplně někde mimo a když je bude překladatel opravovat, tak může i změnit slovosled a vše půjde hladce.

Na místo, kde je {0} se dosadí proměnná zacatek, na místo {1} se dosadí proměnná konec a na místo {2} se dosadí proměnná castka. Navíc můžeme specifikovat formát, v jakém se má částka zobrazit - pokud napíšeme {2:c}, zformátuje se hodnota jako měna (134.5 se zobrazí jako 134,50 Kč) podle toho, jaké jazykové prostředí máte nastaveno v systému Windows (samozřejmě lze ale i říci, že chcete použít nějaké konkrétní, to už je jedno). Dosazené datum se nám zobrazí i s časem, což se nám moc nehodí, takže můžeme napsat {0:d}, aby se zobrazilo jenom datum, tedy 1.1.2007, anebo můžeme napsat {0:D}, aby se vypsalo dlouhé datum, tedy 1. ledna 2007. Podrobnější informace o formátování najdete v nápovědě, jsou tam přesně popsány možnosti formátování a některé předdefinované formáty. Já zde uvedu jen ty nejzajímavější:

Desetiná čísla c měna 134,50 Kč
  f05 číslo na 5 desetinných míst (místo 05 dosaďte požadovaný počet míst) 3,14159
  p02 hodnota v procentech na 2 desetinná místa (číslo se vynásobí 100, takže pro zobrazení 50% předejte hodnotu 0,5) 57,64%
  n03 dlouhá čísla s mezerami a oddělovači tisíců, milionů atd (pro celá čísla zvolte n00) 123 456 789,003
  e06 vědecký formát
(mantisa . 10exponent)
1,346789e+019
Datum a čas d krátké datum 1.1.2007
  D dlouhé datum 1. ledna 2007
  t krátký čas 14:27
  T dlouhý čas 14:27:40
  g krátké datum, krátký čas 31.12.2007 14:28
  G krátké datum, dlouhý čas 31.12.2007 14:28:27
  f dlouhé datum, krátký čas 31. prosince 2007 14:28
  F dlouhé datum, dlouhý čas 31. prosince 2007 14:28:27
  s ISO 8601 (používají některé databáze) 2007-12-31T14:30:28
  r RFC 1123 (standardizovaný formát) Mon, 31 Dec 2007 14:31:29 GMT

Funkce String.Format tedy jako první parametr musí dostat formátovací řetězec, přičemž další parametry (může jich bát libovolný počet) do tohoto řetězce dosadí. Pokud chcete dosazovat vlastní datové typy či objekty, můžete, akorát jim musíte naimplementovat metudu ToString, ale to je nad rámec tohoto článku.

Seznamy pro jakákoliv data

Občas se nám stane, že potřebujeme pracovat s hromadou položek, akorát nikdy nevíme, kolik jich ještě bude. Pokud to víme předem, třeba i těsně před načtením, můžeme si udělat pole potřebné velikosti. Často to ale nevíme, dokud jsme položky nenačetli všechny a nezjistili, že už je konec.

.NET framework má velice hezkým způsobem naimplementovány nafukovací seznamy, které pojmou tolik položek, kolik budeme potřebovat, a navíc mohou být jakéhokoliv typu. Nemusíme do nich ale ukládat jako typ Object a pak vše přetypovávat zase zpět. My již při deklaraci řekneme, že chceme, aby seznam byl na hodnoty typu String. Tento seznam najdeme ve jmenném prostoru System.Collections.Generic.

        Dim seznam As New List(Of String)           'vytvoříme seznam
seznam.Add("první položka") 'přidáme do něj položky
seznam.Add("druhá položka")
seznam.Add(
"třetí položka")
MsgBox(seznam(1).Substring(2))
's položkou pracujeme jako se Stringem
Dim pole() As String = seznam.ToArray() 'ze seznamu můžeme dostat pole Stringů
seznam.RemoveAt(1) 'odebrání prvku ze seznamu
MsgBox(seznam.Count) 'počet prvků seznamu
seznam.Sort() 'setřídění seznamu
seznam.Clear() 'vyprázdnění seznamu

Zde jsou vidět často používané metody, které seznam nabízí. Metoda Add slouží k přidávání položek do seznamu, metoda RemoveAt odebere položku na určitém indexu, vlastnost Count vrací počet položek, metoda Sort umí seznam setřídit a metoda Clear jej vyprázdní.

Ještě je dobré vědět, jak takový seznam funguje uvnitř. Při vytvoření instance třídy má v sobě seznam pole o nějaké počáteční velikosti. Jak do něj postupně přidáváme prvky, pole se jednou zaplní. Jakmile se do něj již prvky nevejdou, vytvoří se nové pole, které je dvakrát větší, stávající hodnoty se do něj překopírují a přidá se nová položka, která se již nevešla. Přidávání je tedy rychlé až na chvíle, kdy se zrovna pole zvětšuje. Naštěstí můžeme v konstruktoru říci, jak velké má být pole na začátku, abychom proces optimalizovali. Výhoda tohoto seznamu je v tom, že jej můžeme použít pro opravdu jakýkoliv datový typ, díky generickému přístupu pouze v závorce za klíčovým slovem Of při deklaraci řekneme, že má být seznam na objekty NetworkStream, a máme nafukovací seznam na objekty, které posílají po síti nějaká data. Navíc je již při kompilaci známo, jakého jsou položky typu, proto když napíšeme seznam(1)., tak se nám hned zobrazí IntelliSense nápověda se všemi dostupnými metodami.

Slovník

Slovník je druhá chytrá věcička, která se nám může hodit. Je to vlastně tzv. name-value kolekce - jedná se o soubor nějakých hodnot, kde každá z nich má svoje jednoznačné ID, podle kterého s ní pracujeme. Používá opět generický přístup, takže jak klíč, tak samotná hodnota, může mít jakýkoliv datový typ na světě. Jak se tedy pracuje se System.Collections.Generic.Dictionary? Jednoduše:

        Dim slovnik As New Dictionary(Of Integer, String)               'vytvoříme slovník
slovnik.Add(1, "jedna") 'přidáme do něj položky
slovnik.Add(2, "dvě")
slovnik.Add(3,
"tři")
slovnik.Add(4,
"čtyři")
If slovnik.ContainsKey(2) Then MsgBox("Dvojka je ve slovníku!") 'je dvojka ve slovníku?
slovnik.Remove(3) 'odebereme trojku
MsgBox(slovnik.Count()) 'zobrazit počet položek
MsgBox(slovnik(4)) 'vypsat čtyřku
slovnik.Clear() 'vyprázdnit slovník

Opět máme metody Add a Remove, metoda Add přidá nějakou hodnotu pod nějakým klíčem, metoda Remove odstraní hodnotu podle klíče. Metoda ContainsKey vrátí True, pokud je nějaký klíč již ve slovníku, slovnik(4) vrátí hodnotu, která je pod klíčem 4, a Count a Clear je stejné, jako u seznamu.

Slovník používá interně nějakou hashovací funkci, takže nalezení položky podle klíče je velmi rychlé.

 

To by bylo pro tento článek asi tak všechno, samozřejmě je to jen zanedbatelná část toho, co nám .NET framework umožňuje, nebavili jsme se o vláknech, neukázali jsme si namespace My, což je jakási VB.NET specialita atd. Ale je jasné, že se tohle vše do jednoho článku nemůže vejít, proto své jakékoliv připomínky pište do diskuse.

 

hodnocení článku

3 bodů / 3 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Všechny díly tohoto seriálu

18. Dědičnost 06.10.2008
17. Objektově orientované programování - základy 30.06.2008
16. Třídy a funkce .NET frameworku, o kterých je dobré vědět 31.12.2007
15. Práce se soubory, úvod do objektově orientovaného programování 19.11.2007
14. Vykreslujeme graf 31.08.2007
13. Úvod do grafiky 27.08.2007
12. Práce s textem a řetězci 17.08.2007
11. Kolekce a pole 27.07.2007
10. Funkce a procedury 01.06.2007
9. Přidáváme druhý formulář 18.05.2007
8. Pole, cykly a práce se soubory 14.05.2007
7. Pole 09.05.2007
6. Cyklus For 05.05.2007
5. Složitější podmínky a rozhodovací struktury 26.04.2007
4. Podmínky a operátory 26.04.2007
3. Proměnné a datové typy 25.04.2007
2. Začínáme programovat 25.04.2007
1. Úvod, vývojové prostředí a základní pojmy 25.04.2007

 

 

 

Nový příspěvek

 

Mr.

1'

csharp|

xml|

css|


'

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

Diskuse: Třídy a funkce .NET frameworku, o kterých je dobré vědět

Dobrý den, chci se zeptat jak můžu vytvořit v vb.net aplikaci, která mi někam zkopíruje nějaký program. Předem děkuji za odpověď.

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

použij FileCopy("zdroj", "cíl").

a příště si vzpomeň na Barta =D : <img src="http://imageproxy.jxs.cz/~nd01/jxs/cz~/8..." alt="Než položím hloupou otázku, použiji Google.">

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

Diskuse: Třídy a funkce .NET frameworku, o kterých je dobré vědět

Výborný článek pro přehled.

A např. najít v MSDN Library něco o formátovacích znacích pro String.Format(), to je prakticky nemožné...alepsoň já to teda nenašel...:)

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

Diskuse: Třídy a funkce .NET frameworku, o kterých je dobré vědět

Kedze tu popisujete, ze StopWatch je presnejsi ako TickCount, skusil som si pre porovnanie urobit kratky test program s dvoma roznymi casovacmi:

1. System.Diagnostics.Stopwatch

2. s vyuzitim Environment.TickCount

a na moje pocudovanie TickCount je presnejsi, pretoze StopWatch mi ide cca 2x pomalsie, ako by mal...? Viete mi povedat preco? Podotykam, ze Visual Studio mam naistalovane vo virtualnej masine, kde aj vyvijam, v PC mam Core2Duo, ale virtualna masina ma pridelene len jedno jadro... myslim si, ze to moze spolu suvisiet, pretoze ked si program skopirujem priamo do mojho PC, tak vsetko ide ako ma.

Vie mi niekto vysvetlit, preco mi vo virtualnej masine ide StopWatch pomalsie ako by mal a ako tento problem odstranit? Pretoze neviem dopredu zistit, ci moj program nebude spustany aj vo virtualnych strojoch?

Dakujem.

PS: so len zaciatocnik, s VB.Net zacinam len s Vasim serialom, ktory je super :)

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

Ve virtuální mašině to může házet nesmysly, tomu bych vůbec nevěřil. TickCount opravdu moc přesný není a StopWatch je přesnější, protože využívá přesný časovač na úrovni hardwaru, pokud je k dispozici.

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

ale ako potom osetrit, aby som mohol cas odmerat presne, aj na virtualnych strojoch, bez obav z pretecenia? Je este nejaka dalsia varianta, ktora pobezi vsade, alebo da sa StopWatch nejak osetrit, aby fungoval vsade?

Dakujem za bleskovu odpoved, necakal som, ze niekto tak skoro odpovie :)

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

Diskuse: Třídy a funkce .NET frameworku, o kterých je dobré vědět

Environment.TickCount na měření délky operace? Ale no tak, od toho máme přece stopky - System.Diagnostics.StopWatch, s přesností na 100 nanosekund.

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

Vždyť v článku píšu, že to není přesné, že to není na nějaké přesné měření. Na běžné použití to však postačuje a je to jednodušší na použití.

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

V tom případě se mi jeví jako lepší řešení uložit aktuální datum před danou operací a po dokončení operace od něj odečíst aktuální datum a získáme TimeSpan. TickCount může přibližně po 25 dnech nepřetržitého provozu (což může být u serverových systémů běžné) přetéct do záporných hodnot.

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

Odpověděl jste mi na otázku, kterou jsem nestačil vyslovit. A jsem rád, že jste můj postup potvrdil.

Tvořil jsem aplikaci zaměřenou na animace a v dostupných příkladech se právě TickCount dost často využívá pro řízení rychlosti této animace, šel jsem původně touto cestou, ale protože jsem také narazil na pár poznámek, že onen TickCount někdy "přeteče" (ač udávali dokonce výrazně kratší čas než Vy), tak jsem šel tou druhou - Vámi navrhovanou cestou. Takže jsem, zřejmě, neudělal ve své volbě žádnou blbost.

Jinak k článku jako takovému, zajímavé, ale zasloužilo by si to skutečně pokračování (a ne jedno).

V jednom bodě bych si ale s autorem dovolil nesouhlasit, a to v otázce hodnocení historického přínosu Mistra Jana z Husi. Je to jistě v mnohém otázkou tradice a zvyklosti, leč naše mluva rodná mně osobně připadá mnohem libozvučnější a krásnější, jsouc zbavena veškěrých spřežek a jiných okras, jaké možno v hojné míře nalézti třeba u našich severních sosuedů.

Ano, v oblasti implementace výpočetní techniky jest krása našeho jazyka vykoupena dílčími problémy, ale rozhodně bych za to nevinil (a neodsuzoval) tohoto osvícence (co by měli říkat všichni, základem jejichž písma zůstala Cyrilice, a to ještě není ten nejkomplikovanější příklad).

Příčinu většiny dnešních problémů bych hledal spíše v letech nedávno minulých, kdy většina podobně "postižených" jazyků byla používána především v teritoriích na opačné straně železné opony, než kam je možno situovat inkubační centra počítačů v podobě, jak je známe dnes, proto také nebyl nikdo, kdo by "naše zájmy" hájil již v počátcích vývoje jednotlivých standardů (tak jako se podařilo velice záhy do standardních ASCII tabulek prosadit speciální znaky pro západoevropslé jazyky (i s diakritikou) - bohužel v mnohém nevyhovující našim potřebám. No a tam Husa neměli!).

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

Asi jsem barbar, ale podle mého názoru není problém podobné skopičiny jako písmena s háčky psát pomocí spřežek, čím méně písmen, tím lépe. Taktéž nechápu, který osel vymyslel 2 písmena, která se vyslovují stejně - I a Y, to je vyložené mrhání písmeny.

Ale to sem teď nepatří.

TickCount přeteče opravdu jednou za 25 dní, je pravda, že to není v mnoha případech vhodná metoda pro měření času. Článek měnit nebudu, ono to zase tolik nevadí.

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

Netvrdil jsem, že jste barbar pouze proto, že máte na některé aspekty lidského bytí jiný názor, než já. A dokonce zastávám podobný pohled "čím méně písmen, tím lépe" jako Vy, neb patřím k plemeni dosti línému. Leč pro mne z daného plyne přesný opak, než jste vyslovil Vy - raději se smířím s přibližně dvěma desítkami písmen vyšperkovaných diakritikou, než celý život furt a stále dokola, místo každého z nich, otrocky zapisovat dvě až tři litery, byť bez háčků a čárek.

S tím I a Y máte celkem pravdu, tam toho přínosu není zas až tolik a jedná se hlavně o zvyk.

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

A ještě bych se vrátil k tomu TickCountu - ve většině případů se s ním asi docela vystačí, v mém konkrétním, kdy počítač poběží nepřetržitě 24 h, 7 dní v týdnu, 365 dní v roce, by mohly nastat nejasnosti.

Ale když už jsme u tohoto tématu.

Je nějak ošetřeno přetečení takovýchto "systémových čítačů"? Jak se v těchto případech systém chová? Načítá stále dál? Jak jsou v následujících dnech (po tom 25. dni) interpretovány hodnoty získané metodou TickCount? Jedná se o hodnotu formátu ULong (bezznaménkové, takže čítač začne opět od 0 a načítá hodnoty), nebo Long (a čítač začne načítat od 0 ale do oblasti záporných čísel, takže vlastně odčítat), nebo se metoda po tom 25. dni zablokuje?

A pokud nebudeme uvažovat problém možného přetečení, je nějaký praktický důvod, proč dát přednost počítání rozdílů "Ticků" na konci a začátku operace před odečítáním časů konce a začátku operace (třeba rychlost,...)?

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

Viktore, už tijede program na ovládání infokanálu? Ozvi se mě prosím na josefmatuska<>seznam.cz . Chtěl bych se tě na něco zeptat. Nem8m se s tebou jak jinak spojit. Díky. Pepa

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

Zdravim, mam dotaz ohledně konverze z verze VB.net 2008 na 2005 a naopak. Doma jsem si nainstaloval Microsoft Visual Basic 2005 Express Edition a doma verzi 2005. K mé nelibosti jsem zjistil, že tyto verze jsou navzájem nekompatibilní. Existuje nějaká možnost jak program napsaný ve verzi 2008 překonvertovat, tak abych ho mohl otevřít a pracovat s ním ve verzi 2005 ?

Předem díky za odpověď

zachs<a>arcww.cz

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

:D malá oprava :

doma 2005 v práci 2008...

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

Kedze tu popisujete, ze StopWatch je presnejsi ako TickCount, skusil som si pre porovnanie urobit kratky test program s dvoma roznymi casovacmi:

1. System.Diagnostics.Stopwatch

2. s vyuzitim Environment.TickCount

a na moje pocudovanie TickCount je presnejsi, pretoze StopWatch mi ide cca 2x pomalsie, ako by mal...? Viete mi povedat preco? Podotykam, ze Visual Studio mam naistalovane vo virtualnej masine, kde aj vyvijam, v PC mam Core2Duo, ale virtualna masina ma pridelene len jedno jadro... myslim si, ze to moze spolu suvisiet, pretoze ked si program skopirujem priamo do mojho PC, tak vsetko ide ako ma.

Vie mi niekto vysvetlit, preco mi vo virtualnej masine ide StopWatch pomalsie ako by mal a ako tento problem odstranit? Pretoze neviem dopredu zistit, ci moj program nebude spustany aj vo virtualnych strojoch?

Dakujem.

PS: so len zaciatocnik, s VB.Net zacinam len s Vasim serialom, ktory je super :)

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

Diskuse: Třídy a funkce .NET frameworku, o kterých je dobré vědět

Dobrý den,

prosím, je nějaký rozdíl mezi pojmem seznam z tohoto dílu pojmem kolekce z dílu 7,8 a 9 ? Dle uvedeného se mi zdá, že je to jedno a totéž, ale proč potom dva pojmy?

Jinak díky za tento seriál, až na drobnosti je velmi srozumitelný, čtivý a přínosný.

Ke cti mu je též, že 28.12.09 je stále živý, takových článků na internetu věru mnoho není!

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

Seznam je jeden druh kolekce. Kolekce je obecně datová struktura, která v sobě drží nějaké položky. Jak konkrétně to dělá, to už je její věc a je mnoho různých způsobů. Seznam je jeden druh kolekce, která si položky uchovává v poli a zachovává jejich pořadí. Takhle ty pojmy používám v článku, ale jinde můžete narazit na jiné názvosloví.

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

Díky moc za reakci, je to jasnější. Tam to bylo v souvislosti s ListView a ListViewItems, zde tedy nově datový typ seznam a objekt List - pomalu si na ty slovíčka zvykám, doufám, že použiji i jinde než pouzde v tomto fóru ;-)

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

Diskuse: Třídy a funkce .NET frameworku, o kterých je dobré vědět

dobrý den,

potřebuji ve VB vyřešit jednoduchou rovnici. čas1 - čas2 = čas3.

čas beru ze systému ve formátu hh:mm:ss.

díky Honza

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

Je naprostý nesmysl odčítat a sčítat časy v textovém formátu. Nechte je normálně v datovém typu Date a odečtěte je.

nahlásit spamnahlásit spam 2 / 4 odpovědětodpovědět

Diskuse: Třídy a funkce .NET frameworku, o kterých je dobré vědět

Dobry den,

omluvam se,ze otravuji diskusi se zrejme hloupym dotazem,ale po nekolika dnech zkouseni uz jsem ztraceny - a uplny zacatecnik. Mam vytvoreny formular s DataGridView pripojeny k dtb MS ACCESS.Data zobrazim v pohode,ale pridat novy zaznam proste nedokazi,resp.pridam ho,ale pak se neulozi do DTB. Cetl jsem Vase i jine diskuse,zkousel,ale proste nic. Nepomohli by jste mi to prosim napasovat na muj kod - prikladam. Protoze problem je nekde mezi mnou a klavesnici a ja uz se fakt vzdavam. DIKY DIKY a prominte

mail:[email protected]

ICQ: 239883444

Public Class frmAdd

    Private Sub STKBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles STKBindingNavigatorSaveItem.Click
        Me.Validate()
        Me.STKBindingSource.EndEdit()
        'Tady jsem zkousel vlozit stkDataSet.AcceptChanges()    - Presto neulozi
        Me.STKTableAdapter.Update(Me.StkDataSet.STK)
        Me.Close()
    End Sub

    Private Sub frmAdd_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'TODO: This line of code loads data into the 'StkDataSet.STK' table. You can move, or remove it, as needed.
        Me.STKTableAdapter.Fill(Me.StkDataSet.STK)
    End Sub

    Private Sub PoznTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PoznTextBox.TextChanged

    End Sub

    Private Sub InvCisloTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InvCisloTextBox.TextChanged

    End Sub

    '''Private Sub BindingNavigatorAddNewItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BindingNavigatorAddNewItem.Click
        Dim drv As DataRowView
        drv = TryCast(Me.STKBindingSource.AddNew, DataRowView)
        If drv Is Nothing Then Return
        Dim cr As stkDataSet.STKRow = _
                    TryCast(drv.Row, stkDataSet.STKRow)
        'Tady jsem zkousel vlozit stkDataSet.AcceptChanges()    - Presto neulozi
    End Sub'''

    Private Sub TypAutaTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TypAutaTextBox.TextChanged

    End Sub
End Class

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

Diskuse: Třídy a funkce .NET frameworku, o kterých je dobré vědět

Zdravím, možná tento kousek kodu někomu pomůže.

Imports Microsoft.Win32
Public Class FRM_RegEdit
    Public regKey As RegistryKey
    Public SubKey As String = "JmenoPodklice"

#Region "Zavedení nového subklíče + vytvoření klíče s hodnotou"
    Private Sub Pridat_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Pridat.Click

        If Me.Klic.Text = "" Then
            MessageBox.Show("Zadej hodnotu klíče")
            Exit Sub
        End If

        regKey = Registry.CurrentUser
        regKey.CreateSubKey(SubKey)
        regKey = regKey.OpenSubKey(SubKey, True)
        regKey.SetValue(SubKey, "" & Me.Klic.Text & ".exe")
        regKey.Close()

        MessageBox.Show("klíč uložen")
    End Sub
#End Region

#Region "Přečtení hodnoty klíče"
    Private Sub Cist_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cist.Click
        regKey = Registry.CurrentUser.OpenSubKey(SubKey, True)
        MessageBox.Show("" & regKey.GetValue(SubKey) & "")
    End Sub
#End Region

#Region "Odstranění subklíče"
    Private Sub Odebrat_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Odebrat.Click

        regKey = Registry.CurrentUser
        regKey.DeleteSubKey(SubKey, True)
        regKey.Close()
        MessageBox.Show("Klíč byl odebrán")
    End Sub
#End Region

End Class
nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • 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