NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
Avatar
rawen
Člen
Avatar
rawen:27.1.2018 14:03

Zdravím, řeším takovou věc. Chtěl bych mít vlákno, které bude v časovém intervalu provádět nějakou operaci a současně byla možnost vynutit provedené této operace okamžitě v daném vláknu. Přikládám ukázkový kód.

/// <summary>
/// Vlákno, provádějící kontrolu.
/// </summary>
private Thread t;

private void ZahajeniKontroly()
{
    t = new Thread(new ThreadStart(ZkontrolujData));
    t.Start();
}

private void ProvedKontrolu()
{
    // TODO: Probuzení vlákna
}

private void ZkontrolujData()
{
    // Inicializace dat pro kontrolu

    while (true)
    {
        // Provádění kontroly

        Thread.Sleep(60000);
    }
}

Po zahájení kontroly bude každou minutu probíhat kontrola dat. Chtěl bych metodou ProvedKontrolu probudit vlákno, aby nečekalo do provedení minutového intervalu, ale provedlo svojí práci okamžitě. Nechci vytvářet nové vlákno a inicializovat všechny proměnné jen kvůli jednomu cyklu. Předem děkuji za každý nápad nebo radu.

Odpovědět
27.1.2018 14:03
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na rawen
ostrozan:27.1.2018 16:51

Zapomeň na vlákna :)
C# má mnohem lepší nástroje- třeba Timer resp. DispatcherTimer ve wpf
Když vidím :

Thread.Sleep(60000);

Jdou na mně mdloby :)
No a z toho timeru můžeš pak spustit Backgroundworker, nebo Task - ty pak můžeš taky volat odkud chceš

Akceptované řešení
+20 Zkušeností
Řešení problému
 
Nahoru Odpovědět
27.1.2018 16:51
Avatar
HONZ4
Člen
Avatar
Odpovídá na rawen
HONZ4:27.1.2018 21:32

Souhlasím s tím co napsal ostrozan, ale pokud by jsi chtěl trvat na svém řešení, tak by se to dalo udělat například takto:

private Thread t;

private void ZahajeniKontroly()
{
    t = new Thread(new ThreadStart(ZkontrolujData));
    t.Start();
}

private void ProvedKontrolu()
{
  if(!probiha_provadeni_kontroly)ProvadeniKontroly();
}

private bool probiha_provadeni_kontroly = false;

private void ZkontrolujData()
{
    while (true)
    {
        if(!probiha_provadeni_kontroly)ProvadeniKontroly();
        Thread.Sleep(60000);
    }
}

private void ProvadeniKontroly()
{
   probiha_provadeni_kontroly = true;
   // Inicializace dat pro kontrolu (  pokud to bude nutné zde )
   // Provádění kontroly
   probiha_provadeni_kontroly = false;
}
Editováno 27.1.2018 21:34
 
Nahoru Odpovědět
27.1.2018 21:32
Avatar
rawen
Člen
Avatar
Odpovídá na HONZ4
rawen:27.1.2018 23:19

V tomto případě pokud bych zavolal metodu ProvedKontrolu by se metoda ProvadeniKontroly nevolala ve vedlejším vlákně. Vyrábět kvůli tomu nové vlákno bych nechtěl, zkusím to tím druhým způsobem, ale děkuji.

Nahoru Odpovědět
27.1.2018 23:19
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
rawen
Člen
Avatar
Odpovídá na ostrozan
rawen:27.1.2018 23:38

Pokud bych ale každou minutu vytvářel nový Backgroundworker, tak nebude to moc časově/procesorově náročné? Je možné, že by se třeba ta kontrola prováděla i každých 10sekund.

Nahoru Odpovědět
27.1.2018 23:38
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
rawen
Člen
Avatar
Odpovídá na ostrozan
rawen:27.1.2018 23:53

Aha, ono stačí vytvořit jen jeden BackgroundWorker a jen ho zapínat, já jsem si myslel, že když se provede událost .RunWorkerCom­pleted, že dojde k úplnému uvolnění zdrojů a nejde dál používat. :)

Nahoru Odpovědět
27.1.2018 23:53
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
ostrozan
Tvůrce
Avatar
ostrozan:28.1.2018 18:48

Hodně záleží, co ta tvoje kontrola vlastně dělá - jak je časově náročná

  • můžou to být jednotky milisekund, pak bys to mohl obsloužit přímo v ticku toho timeru
  • při delších časech pak máš na výběr mezi tím Backgroundworekrem a Taskem - každý má své výhody a nevýhody - Task se mi ale zdá jednodušší na použití

Pokud bych ale každou minutu vytvářel nový Backgroundworker, tak nebude to moc časově/procesorově náročné?

naopak já si myslím, že je zbytečné ho držet v paměti celou dobu, když ho potřebuješ jednou za minutu - odhaduju na pár milisekund

 
Nahoru Odpovědět
28.1.2018 18:48
Avatar
rawen
Člen
Avatar
Odpovídá na ostrozan
rawen:30.1.2018 8:00

To není úplně jednoznačné jak často se ta kontrola bude provádět. Je to někde mezi 5s až 1min. Ta kontrola spočívá pouze v serealizaci dat a jejich odeslani. Časově to vychází kolem 10ms. Myslíš, že kdybych ho potřeboval využívat třeba i těch každých 5s, že bude lepší si ho vytvořit vždy nový a v události .RunWorkerCompleted si ho Disposovat? :)

Nahoru Odpovědět
30.1.2018 8:00
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
ostrozan
Tvůrce
Avatar
ostrozan:30.1.2018 10:51

10 ms bych vůbec neřešil asynchronní operací
pokud to potřebuješ dělat periodicky , tak použij ten timer a spouštěj to na událost Tick - a pak vždy kdy budeš potřebovat.

pokud to ale chceš mermomocí spouštět asynchronně - použij spíš ten Task - způsobů jak ho použít je víc - tady je takové shrnutí

BackgroundWorker je asi v tvém případě zbytečný - je to takový relikt starých časů - a možná, kdyby bývali přišli s Taskem dříve, tak by asi ani nevznikl

a k tvé poslední otázce - všeobecně pro jakýkoliv objekt - i 5 sekund je v počítačovém čase strašně dlouhá doba a je zbytečné ho tam držet, kvůli použití na 10 ms

 
Nahoru Odpovědět
30.1.2018 10:51
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 9 zpráv z 9.