Formy a vlákna – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Formy a vlákna – .NET – Fórum – Programujte.comFormy a vlákna – .NET – Fórum – Programujte.com

 

Kartmen
~ Anonymní uživatel
57 příspěvků
13. 5. 2021   #1
-
0
-

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í.

Nahlásit jako SPAM
IP: 88.103.206.–
JerryM0
Věrný člen
14. 5. 2021   #2
-
0
-

jsi si jistý že se chceš učit starej .NET WinForms ? nechceš radši novej WinUI 3.0 pro Windows 10 ? jde o to, že starej WinForms už nikdo nechce ...

https://docs.microsoft.com/en-us/windows/apps/winui/

https://docs.microsoft.com/en-us/windows/apps/winui/winui3/get-started-winui3-for-desktop

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:892b:f6e7:b8cd:4d02...–
gna
~ Anonymní uživatel
1891 příspěvků
14. 5. 2021   #3
-
0
-

Myslím si, že Controly by mělo jít vytvořit v jiném vlákně a jen ten Add bude potřeba ve vlákně UI.

Když ta data mění form, tak bych je posílal postupně jednotlivě, bez fronty. Invoky se provádějí taky postupně, pokud nebudeš přistupovat ke sdíleným datům, tak to sám synchronizovat nemusíš.

Čekání na dokončení záleží na tom, co přesně potřebuješ dělat. Když pošleš X úloh, tak po X výsledcích je hotovo, asi není potřeba mít někde blokující čekání.

Nahlásit jako SPAM
IP: 213.211.51.–
Kartmen
~ Anonymní uživatel
57 příspěvků
15. 5. 2021   #4
-
0
-

#2 JerryM
Já se to už úplně neučím, nějaký rok to používám, jen až teď s tím dělam něco složitějšího, jako jsou ty vlákna, nebo pokus o vlastní rendering, když se mi nelíbí ten defaultní. Ve firmě se to používá, ale dřív jsem zkoušel WPF. Ale ani tyto staré formuláře mi nepřijdou špatné, pro přebrání hodnot to stačí, nebo co je na tom tak špatného a co zásadního mají novější technologie? Co vim, tam WPF má navíc různé kravinky jako jsou barevné přechody a všelijaké efekty, ale to je tak do her, spíš než do kancelářské aplikace. Jsou ale nějaké věci, které by se mi hodili, ale nejsou implementované, možná v něčem novějším ano. Např. v DataGridViewu není možnost vytváření tabulek jako to dokáže Excel co se spojování (Merge) buněk týče, když chci např. dvě buňky vedle sebe zcelit tak, aby se následně text centroval na střed této spojené buňky. 

Nahlásit jako SPAM
IP: 78.80.151.–
JerryM0
Věrný člen
15. 5. 2021   #5
-
0
-

přiznám se že z tvýho popisu problému stejně nechápu co chceš ..  je taky zajímavý že když děláš programátora že tě firma ještě nedonutila přejít na WPF ... ale to neva ...

1/ není nutné vytvářet "ručně" všechny Controls ve vlákně kde vznikl Form1 : Form, pokud to nechceš dávat do instrukcí VisualDesigneru což je ve WinForms (WF) blbost. Měl bys pochopit, že starý WF není XAML a nejde si tak nějak přilinkovat další XAML s dalšími instrukcemi... Control mužeš přidat do Formu kde chceš ale musíš od toho Formu kam to přidáváš mít Handle, což je pochopitlené

2/ WF jsou jednovláknová !!! takže pokud si vytvoříš vlastní vlákna výpočtu, tak pak k WF přistupuješ tak jako tak jako k jednovláknové aplikaci ... tady uvádíš málo detailů ...

3/ přiznám se že z popisu problému se nedá odvodit co vlastně chceš ... vlákna jsou vlákna .. jestli je potřebuješ synchronizovat jsou na to prostředky v .NETu dostatečné .. před ukončením aplikace je vhodné všechny tvoje vlákna ukončit to je samozřejmý ...

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:19aa:11f4:e7c4:4c5a...–
Kartmen
~ Anonymní uživatel
57 příspěvků
15. 5. 2021   #6
-
0
-

#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
          //...
        }
      }
    }
Nahlásit jako SPAM
IP: 88.103.206.–
Kartmen
~ Anonymní uživatel
57 příspěvků
15. 5. 2021   #7
-
0
-

#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.

Nahlásit jako SPAM
IP: 88.103.206.–
JerryM0
Věrný člen
15. 5. 2021   #8
-
0
-

#7 Kartmen
nevim jestli jde ve WF slučování buněk v DataGridView, ale jsou tu tyto komponenty od Telerik a DevExpress a dalších firem a tam už by to jít mělo ...

https://docs.telerik.com/devtools/wpf/controls/radgridview/features/merged-cells

https://www.infoq.com/research/dotnet-web-components/

v každém případě to jde u komponent pro WPF od DevExpress a Telerik .. .

https://www.telerik.com/support/kb/winforms/gridview/details/radgridview-merge-celss

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:19aa:11f4:e7c4:4c5a...–
JerryM0
Věrný člen
15. 5. 2021   #9
-
0
-

jinak jestli vytváříš ručně Formulář WF s komponentama tak to je docela masochismus ... je tam přeci VisualDesigner ne ?

1/ pro jedoduchý formulář mužeš využít MessageBox

2/ pokud potřebuješ nutně aby běželo více Forms současně máš dvě možnosti: buď si každý formulář sestavíš jako samostatný EXE/DLL soubor a komunikace mezi hlavním/řídícím souborem je udělaná pomocí PIPEs což je nejjednodušší a nejrychlejší na práci a taky nejrychlejší na kompilaci nebo ... použiješ ty tvoje Threads/vlákna :) ha ha . V obojím případě se mužeš pomocí BINDING napojit na nějakou databázi a číst a zapisovat data .. ty tvoje příklady s INVOKE .. nějak nechápu, a je potřeba upozornit, že tohle řešit pomocí Thread je poměrně náročné ... jestli jich máš víc budeš muset možná používat i Mutex:

https://docs.microsoft.com/cs-cz/dotnet/api/system.threading.mutex?view=net-5.0

a Thread.Sleep(...)

tady to je popsaný ..

https://stackoverflow.com/questions/34524/what-is-a-mutex

tvoje Lock ti asi moc nepomuže .. to je atomické uzamčení a používá se např. pro generování náhodného čísla v .NET WinForms .. pomocí příkazů Monitor.Enter(mujRandom), Monitor.Exit(mujRandom).. chápeš jo ?

a tady je příklad na Thread na Form:

https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.invoke?view=net-5.0

threat se spouští příkazem Thread.Start. Pomocí Invoke se volá nějaká konkrétní metoda ve třídě.

3/ děláš si to moc složitý .,..

ta vaše firma je docela zajímavá firma .. tam bych chtěl pracovat  :) bere u vás programátor aspoň 60000Kč měsíčně ?  nebo víc ??? 100000Kč ???

když používáš vlákna měl bys vědět, že memory management operačního systému rozděluje práci na jednotlivá jádra zcela samostatně a nedá se do toho šťourat. abys to pochopil ... tak ... když si uděláš 10 vláken a každý bude počítat něco v nekonečný smyčce a pustíš to na 10ti jádrovým procesoru - lhostejno jestli 10 fyzických nebo 10 logických jader tak ho tim zatížíš na 99procent .. chápeš jo ? Na 8 mi jádrovým už takovej program zahltí procesor tak, že stejně tvoje aplikace už vubec nebude reagovat ... budeš muset vkládat sekvence typu Application::DoEvents() nebo Thread::Sleep(...) ....  už to chápeš ????

pokud tvuj program běží a chceš ho ukončit tak musíš nejprve ukončit všechna vlákna  a pak dát null na použité handly a případně i dispose na některé objekty protože jinak to selže .. dojde k chybě .. vlákno musí někomu patřit ...

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:19aa:11f4:e7c4:4c5a...–
JerryM0
Věrný člen
15. 5. 2021   #10
-
0
-

#1 Kartmen
https://www.itnetwork.cz/csharp/vlakna/c-sharp-net-tutorial-vlakna-sleep-join-lock

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:19aa:11f4:e7c4:4c5a...–
Kartmen
~ Anonymní uživatel
57 příspěvků
15. 5. 2021   #11
-
0
-

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á.

Nahlásit jako SPAM
IP: 88.103.206.–
JerryM0
Věrný člen
15. 5. 2021   #12
-
0
-

aha už sem to pochopil ty seš duchodce co se nudí ... njn ... svět už je takovej ...

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:19aa:11f4:e7c4:4c5a...–
JerryM0
Věrný člen
18. 5. 2021   #13
-
0
-

https://stackoverflow.com/questions/16774966/how-to-merge-datagridview-cell-in-winforms

Nahlásit jako SPAM
IP: 2a00:1028:83be:235a:4ce0:298e:96d8:e5b9...–
Kartmen
~ Anonymní uživatel
57 příspěvků
19. 5. 2021   #14
-
0
-

DevExpress a Telerik jsou placené. Ten návod na stackoverflow jsem našel, ale to není zcelování buněk, to je jen zamaskování, které tak trochu vypadá tím, že jsou nějaké okraje viditelné a jiné ne, ale nejde v tom centrovat text na střed sloučené buňky... stále jsou tam všechny a do jedné z nich se např. text musí zapsat.

Našel jsem jednu výhodu WPF a tou je překreslování okna, které se ve WinFormech vykresluje po částech (controlech) a tedy problikne během překreslování leccos, co jsem četl, tak ve WPF by to dělat nemělo.

Nahlásit jako SPAM
IP: 78.80.151.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 38 hostů

Podobná vlákna

Normální formy — založil petr.satka

Normální formy — založil Jan

Predavani dat mezi formy — založil Jirka

Vlákna — založil Tayson

 

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