Diskuze: Stopky
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


Zobrazeno 15 zpráv z 15.
K personalizaci obsahu a reklam, poskytování funkcí sociálních médií a analýze naší návštěvnosti využíváme soubory cookie. Informace o tom, jak náš web používáte, sdílíme se svými partnery pro sociální média, inzerci a analýzy. Partneři tyto údaje mohou zkombinovat s dalšími informacemi, které jste jim poskytli nebo které získali v důsledku toho, že používáte jejich služby.
Používáme nezbytné cookies pro fungování webu a s tvým souhlasem také analytické a marketingové cookies.
Zajišťují základní funkce, bezpečnost a služby, které sis vyžádal. Nelze je vypnout.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| ITnetwork | ITnetwork | Provoz webu, relace, přihlášení a uložení nastavení cookies. | PHPSESSID, auth_token, sid, itn_consent_impression, __Host-itn_consent | Relace až 1 rok |
| Google Tag Manager | Správa značek a načítání měřicích nástrojů webu. | Žádné | Neukládá se | |
| Google Fonts | Načítání typografie webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google Hosted Libraries | Načítání potřebných knihoven a stylů webu. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele | |
| Google reCAPTCHA | Ochrana formulářů a webu před zneužitím. | _GRECAPTCHA, rc::a, rc::b, rc::c, rc::f | Relace až 180 dní | |
| YouTube | Přehrávání vloženého video obsahu. | localStorage, IndexedDB; cookies after playback interaction | Relace až trvalé úložiště | |
| Vimeo | Vimeo | Přehrávání vloženého video obsahu. | __cf_bm, _cfuvid, vuid, localStorage, IndexedDB | Relace až 2 roky |
| Facebook Login | Meta | Přihlášení pomocí účtu třetí strany. | Úložiště řízené poskytovatelem | Relace až 1 rok |
| GoPay | GoPay | Zpracování uživatelem vyžádané platby. | Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
Pomáhají nám porozumět používání webu a zlepšovat ho.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Analytics 4 | Měření návštěvnosti a používání webu. | _ga, _ga_* | Až 2 roky | |
| Microsoft Clarity | Microsoft | Měření návštěvnosti a používání webu. | _clck, _clsk, _cltk | Relace až 1 rok |
Slouží k měření kampaní, personalizaci reklamy a marketingové komunikaci.
| Služba | Poskytovatel | Účel | Cookies a úložiště | Doba uložení |
|---|---|---|---|---|
| Google Ads | Měření kampaní, reklama a remarketing. | _gcl_au, _gcl_ls | Relace až 90 dní | |
| Meta Pixel | Meta | Měření kampaní, reklama a remarketing. | _fbp, _fbc, localStorage | Až 90 dní |
| Sklik | Seznam.cz | Měření kampaní, reklama a remarketing. | retargeting, sid, szn:* | Relace až trvalé úložiště |
| LinkedIn Insight | Měření kampaní, reklama a remarketing. | bcookie, li_gc, lidc, __cf_bm | Relace až 1 rok | |
| Ecomail | Ecomail.cz | Měření kampaní, reklama a remarketing. | ecmid, Úložiště řízené poskytovatelem | Dle podmínek poskytovatele |
| Atribuce kampaní ITnetwork | ITnetwork | Přiřazení návštěvy a objednávky ke kampani. | campaign_clid[*], user_session_context | Až 1 rok |
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


Nikdo to za tebe dělat nebude. Použij Timer nebo vlákno na pozadí.
Úplně nejjednodušší by bylo po kliknutí na checkbox zobrazit nějaké upozornění, potom uspíš vlákno na 40 minut:
System.Threading.Thread.Sleep(1000*60*40);
a potom zobrazíš další zprávu, že 40 minut uběhlo
Na první pohled dobrá rada, bohužel s nulovou šancí na úspěch.
Je k tomu plno důvodů.. například tyto:
Takže toto řešení je plně špatné. Myšlenka dobrá, bohužžel to takto nepůjde.
*winforms, swing.. proste cokoliv..
Metoda Sleep by se neměla používat pro běh programu. Je to metoda určená například k testování. Je to uvedeno i v dokumentaci MSDN.
Já bych to osobně vyřešil Timerem, nebo bych si udělal vlákno, kde bych pomocí zmíněné metody čekal X času a pak bych zavolal callback.
Pomocí Timeru:
//Designér - PSEUDOKÓD:
Timer tmrWait; //Deklarace timeru
tmrWait.Interval = 1000*60*40 //Interval timeru
tmrWait.Tick = (metoda) tmrWait_Tick; //Handler události "Tick", zavolá se až uběhne interval
//Následně někde ve třídě:
private void tmrWait_Tick(object o, EventArgs e){ //Metoda, handler události
MessageBox.Show("Uběhlo."); //Kód handleru
}
Pomocí vlákna:
void Wait(){ //Metoda, která se zavolá, když se má čekat
Action callback = () => { //Callback
MessageBox.Show("Uběhlo."); //Kód v callbacku
};
Thread waitThread = new Thread(new ThreadStart( () => { //Vlákno
Thread.Sleep(1000*60*40); //Počkáme 40m
callback(); //Zavoláme callback
}));
}
Problém je ten, že v podstatě nemůžeš pozastavit běh programu na nějakém bodě a "ono to bude nějak reagovat", message loop běží ve stejném vlákně jako tvůj kód, jestli ho zamrazíš, aplikace nebude reagovat.
Takže to se musí udělat tak, že to co má být za tím čekáním se umístí do nějaké metody, která se zavolá po určitém čase buďto tím Timerem nebo vláknem.
BTW, dávej si pozor, nemůžeš nijak s formulářem manipulovat (ani s prvky) jestliže se o to snažíš v jiném vlákně než message loop formuláře, vyhodí ti to vyjímku TargetInvocationException.
Kód pro manipulaci formuláře musíš spustit ve vlákně s formulářem samotným, použij metodu Invoke (případně BeginInvoke, jestli nechceš čekat na dokončení kódu).
Elegantnější mě ale přijde řešení pomocí vlákna.
Nevím, který článek si četl, ale na tomto MSDN článku který jsem vygooglil ( https://msdn.microsoft.com/…vs.110).aspx ) je napsáno něco jiného:
However, we recommend that you use other System.Threading classes such as Mutex, Monitor, EventWaitHandle, or Semaphore instead to sychronize threads or manage resources.
V překladu:
Místo toho ale doporučujeme používat jiné třídy nacházející se v System.Threading, například Mutex, Monitor, EventWaitHandle nebo Semaphore na synchronizaci vláken nebo správu prostředků.
Synchronizaci vláken neprovádíme ani nespravujeme prostředky, nevidím tedy důvod proč ji nepoužít.
NO.. uplne nejjednodušší řešení a nejpochopitelnější pro začítečníka, je prostě pustit BackgroundWorker, na ten čas ho sleepnout a pak v OnCompleted udělat věci na UI. celé se to dá napsat defakto na 4 řádky pomocí lambdy.
nejjednodušší pro začátečníka a pak zmíníš lambdy? Hmmm... tak si ne no.
Na časování je časovač - timer
jak vás vůbec může napadnout na 40 minut uspávat cokoliv - ať už jiné
vlákno, nebo backgroundWorker?
když jsme u nesmyslů (i když funkčních) přidám ještě jeden
DateTime date = DateTime.Now;
long start = date.Ticks;
long end = start + 24000000000; //24000000000 tiku je 40 minut
while (date.Ticks<end)
{
date = DateTime.Now;
}
MessageBox.Show("Uběhlo 40 minut");

busy waiting? jako vazne? Tak ty jsi jinaci master
Neuspíš vlákno, což sežere 0
0 výkonu a pak tam napereš busy waiting
jdi si lehnout.. to snad ani jako
vtip neni dobre 
Pravděpodobně nemáš v pět hodin ráno náladu na vtipy 
ale k tvé otázce:
ano - myslím to smrtelně vážně - jako příklad toho nejhoršího řešení
- absurdity dovedené k dokonalosti, toho,že může existovat ještě něco
horšího než pro čekání zakládat vlákno, které má jediné poslání -
spát. Nehledě na to, že jak se lze dočíst v dokumentaci tak skutečný čas
se od nastaveného liší - a vůbec bych se nedivil, kdyby při požadovaných
40ti minutách byla chyba v řádech minut.
Pokud ale slova
když jsme u nesmyslů (i když funkčních) přidám ještě jeden
málo vystihují co jsem měl na mysli, tak teď to snad pochopíš
Jde o to, že .NET tě nechá spáchat spoustu nelogických konstrukcí a aplikace přitom bude "fungovat", což ale neznamená, že je dobré je používat.
kdyz nespim, tak ne
Tak
ted tu muzeme rozebrat jak funguji timer a co dela CreateTimerQueueTimer
Do až tak akademické diskuse bych nezabředal 
ale i tak - zde je mých pět minut práce:
public partial class MainWindow : Window
{
DispatcherTimer timer;
DateTime startTime, stopTime;
public MainWindow()
{
InitializeComponent();
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMinutes(40);
timer.Tick += timer_Tick;
}
private void button_Click(object sender, RoutedEventArgs e)
{
button.Content = "čekej";
button.IsEnabled = false;
timer.Start();
startTime = DateTime.Now;
}
void timer_Tick(object sender, EventArgs e)
{
stopTime = DateTime.Now;
timer.Stop();
TimeSpan ts = stopTime - startTime;
string str = "Uplynulo " + ts.Minutes.ToString() +" min " +ts.Seconds.ToString()+" sec " + ts.Milliseconds.ToString()+" ms";
MessageBox.Show(str);
button.Content = "spustit časování";
button.IsEnabled = true;
}
}
není to sice žádný atomový čas - viz obrázek , ale i tak 7 ms na 40ti minutách je myslím slušný výsledek a podle analýzy procesor ani nezaregistroval, že se něco děje
když se ti bude chtít můžeš stejných pět minut věnovat "spícímu
vláknu" 
Zobrazeno 15 zpráv z 15.