Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
PetJan
Člen
Avatar
PetJan:4.2.2019 11:41

Ahoj, mám několik programů, kde se mi stále opakují některé třídy a formuláře. Rozhodl jsem se je přesunout do jedné dll knihovny, abych je mohl používat snadněji. Vše se mi celkem daří přesunout, ale narazil jsem na problém s BackgroundWorker, který v tomto případě používám aby mi běžel ProgressBar,.

Zkusil jsem: Dokážu si do dll něco poslat (jako parametry metody) i poslat zpět výsledek (pomocí veřejné proměnné), ale problém je, že pokud v dll něco spustím v jiném vlákně, tak samozřejmě poslání zpět nefunguje = když se v dll dostanu k RunWorkerCompleted, původní vlákno už je dokončené.

Chci docílit: Nevím, zda dokážu v dll nějakým způsobem pracovat s komponentami z volajícího programu.
Např. pokud bych měl na formuláři ve volajícím programu Label tak zda mu dokážu nějak v RunWorkerCompleted které je v dll přiřadit hodnotu: label.text = "pokus".
Případně mě ještě napadá čekat na dokončení BackgroundWorker, jenže většina čekání, které mě napadá zase zablokuje hlavní vlákno, a tím ProgressBar stojí.

 
Odpovědět
4.2.2019 11:41
Avatar
Petr Jílek
Člen
Avatar
Petr Jílek:4.2.2019 18:09

Ahoj, samozřejmě to jde. Já bych použil delegáty a při volání funkce jeden z parametrů metody by byla proměnná typu generický delegát např. Action<string> callback

volání delegáta se pak provádí callback.Invo­ke("pokus");

a v tomhle případě bych se vykašlal na background worker a rovnou to spustil pomocí Task třídy.

Nicméně moc nechápu to volání z vlákna, které je už dokončené...pokud je myšleno že například formulář, ze kterého byl otevřen nový thread byl mezitím už zavřen... tak to se dá při zpětném volání pomocí delegáta udělat např takto.

if this.Disposed == false
{
this.Invoke(ná­vrathodnota); 'invoke se musí použít kvůli volání prvku ve formuláři z jiného než main vlákna
}

snad je to trošku srozumitelný :)

 
Nahoru Odpovědět
4.2.2019 18:09
Avatar
Petr Jílek
Člen
Avatar
Odpovídá na Petr Jílek
Petr Jílek:4.2.2019 18:23

ted ještě koukám, že v tý rychlosti jsem to trošku pomotal :) Ten kód co se spouští při zpětném spuštění delegáta už ve formuláři tak by byl asi takto (pouze pro winforms)

if (this.Disposed == false)
{
this.Invoke(() => this.label.text = navrathodnota); //lambda pro volání prvku formuláře...
}

te´d už to mám snad správně :) kdyby jsi měl potíž, napíšu tu proceduru včetně volání celou... nicméně pročti tady na itnetwork články o delegátech...

 
Nahoru Odpovědět
4.2.2019 18:23
Avatar
PetJan
Člen
Avatar
PetJan:4.2.2019 18:50

Díky za radu. Delegáty jsem zatím nikdy nepoužíval a budu se na ně muset nejprve podívat. :).

Nakonec jsem to vyřešil pomocí události, mimochodem tu jsem použil taky poprvé :).

V té dll jsem vytvořil událost a v RunWorkerCompleted ji naplnil výsledky toho co se zpracovalo v DoWork. Pak jsem v programu, který použil dll událost zachytil a data co vrátila zpracoval.
Asi to nepopisuji správnými slovy, ale berte to s reservou jsem samouk ;).

 
Nahoru Odpovědět
4.2.2019 18:50
Avatar
Petr Jílek
Člen
Avatar
Odpovídá na PetJan
Petr Jílek:5.2.2019 6:16

No událost je taky vlastně druh delegáta (v kolekci) a funguje stejně ;)

Tak aspoň že to funguje. Backround worker vrací řízení zpět do původního vlákna. Což je pro obsluhu formuláře fajn. Kdybys to chtěl dělat jen pomocí task nebo si spustit thread ručně, tak nezapomeň volat prvky formuláře pomocí invoke. Usuzuji používáš winforms podle toho volání labelu

 
Nahoru Odpovědět
5.2.2019 6:16
Avatar
PetJan
Člen
Avatar
PetJan:5.2.2019 9:51

Jojo ve všem máš pravdu, používám VB.NET a winforms.
Měl jsem podezření, že ty události mají s delegáty dost společného.
Původně jsem se rozhodovat mezi thread a BackgrounWorkerem a ten druhý to vyhrál. Dobře se s ním pracuje a není to tolik náchylné na moje chyby z neznalosti a blbosti.
Ještě jednou díky.

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