NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
Avatar
thebestgamesify:6.7.2016 17:02

čaute , nevie tu niekto naprogramovat niečo take že uživatel len klikne na check box zobrazi sa mu 40minut bolo nastavenych a po 40minutach sa mu ukaže message box 40minut ubehlo ? ?
Ak ano prosim či by to niekto nevedel spravit a poslat sem diky

 
Odpovědět
6.7.2016 17:02
Avatar
Petr Čech
Tvůrce
Avatar
Odpovídá na thebestgamesify
Petr Čech:6.7.2016 17:05

Nikdo to za tebe dělat nebude. Použij Timer nebo vlákno na pozadí.

Nahoru Odpovědět
6.7.2016 17:05
the cake is a lie
Avatar
Petr Šťastný
Tvůrce
Avatar
Odpovídá na thebestgamesify
Petr Šťastný:6.7.2016 17:09

Ú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

 
Nahoru Odpovědět
6.7.2016 17:09
Avatar
Odpovídá na Petr Šťastný
Marian Benčat:6.7.2016 22:38

Na první pohled dobrá rada, bohužel s nulovou šancí na úspěch.

Je k tomu plno důvodů.. například tyto:

  1. Všechny UI frameworku (WPF, WebForms) jsou cele pohaneny jedním jediným vláknem a to má na starost nejen logiku, ale i třeba rendering a message bus.. Takže UI mu na 40 minut vytuhne
  2. Co je horší, 40 miut bude zablokované celé toto vlákno, takže se začnou kupit do stacku zpráv zprávy a aplikace zhruba po 5ti minutách spadne na to, že se zahltila tato message bus fronta a on není schopný už recovernout...
  3. Pokud aplikace nebude delší dobu reagovat, windows ji označí jako v deadlocku a označí jako že neodpovídá.

Takže toto řešení je plně špatné. Myšlenka dobrá, bohužžel to takto nepůjde.

Editováno 6.7.2016 22:38
Nahoru Odpovědět
6.7.2016 22:38
Totalitní admini..
Avatar
Marian Benčat:6.7.2016 22:42

*winforms, swing.. proste cokoliv..

Editováno 6.7.2016 22:42
Nahoru Odpovědět
6.7.2016 22:42
Totalitní admini..
Avatar
Odpovídá na Petr Šťastný
Ladislav Ondris:8.7.2016 7:56

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.

Nahoru Odpovědět
8.7.2016 7:56
Pokud neděláš chyby, nepracuješ na dostatečně těžkých problémech.
Avatar
VitekST
Člen
Avatar
VitekST:8.7.2016 17:22

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 TargetInvocati­onException.

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.

Editováno 8.7.2016 17:24
 
Nahoru Odpovědět
8.7.2016 17:22
Avatar
VitekST
Člen
Avatar
Odpovídá na Ladislav Ondris
VitekST:8.7.2016 17:37

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.

 
Nahoru Odpovědět
8.7.2016 17:37
Avatar
Marian Benčat:8.7.2016 21:03

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.

Nahoru Odpovědět
8.7.2016 21:03
Totalitní admini..
Avatar
Odpovídá na Marian Benčat
Michal Žůrek - misaz:8.7.2016 21:44

nejjednodušší pro začátečníka a pak zmíníš lambdy? Hmmm... tak si ne no.

Editováno 8.7.2016 21:44
 
Nahoru Odpovědět
8.7.2016 21:44
Avatar
ostrozan
Tvůrce
Avatar
ostrozan:8.7.2016 22:39

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");
:-) :-) :-)
 
Nahoru Odpovědět
8.7.2016 22:39
Avatar
Marian Benčat:11.7.2016 5:01

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 :-)

Editováno 11.7.2016 5:02
Nahoru Odpovědět
11.7.2016 5:01
Totalitní admini..
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na Marian Benčat
ostrozan:11.7.2016 20:19

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.

Editováno 11.7.2016 20:20
 
Nahoru Odpovědět
11.7.2016 20:19
Avatar
Marian Benčat:12.7.2016 1:54

kdyz nespim, tak ne :D Tak ted tu muzeme rozebrat jak funguji timer a co dela CreateTimerQu­eueTimer

Editováno 12.7.2016 1:55
Nahoru Odpovědět
12.7.2016 1:54
Totalitní admini..
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na Marian Benčat
ostrozan:13.7.2016 16:06

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" :-)

 
Nahoru Odpovědět
13.7.2016 16:06
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 15 zpráv z 15.