Backgroundworker - ukončení v průběhu výpočtu   otázka

C#, Threading, WinForms

Zdravíčko,

prosím Vás mám desktopovou aplikaci - deskova hra. Používám Background worker pro vymýšlení tahů, když hraje PC.

Problem ale nastane tehdy, když PC přemýšlí a já změním jeho úroveň. Pak dostanu výjimku, že bw nemůže běžet víckrát. Takže má otázka je: jak bw předčasne ukončit?

Metoda CancleAsync() neni pro me vhodna - ukonceni nastane, az kdyz je vypocet ukonce. ale to neni dobre, uz jen proto, ze clovek musi cekat. to je spatne.

K vymýšlení tahu mám třídu Brain a statickou metodu GetBestTurn, klasicky minimax, řekl jsem si, že k předčasnému ukončení použiju zámek - statickou promenou lock, pokud je true, tak vypocet se ukonci a vrati souradnice s -1,-1. Kdyz je lock false, tak vypocet probehne korektne. Jenze ani tohle neni reseni, protoze (asi!!!) ohodnocovaci funkce taky zabere nejaky cas, takze driv nez se projevi zamek, tak nastane vyjimka.

Můžet mi poradit nejake vhodne reseni? :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nejspíš jsem problém vyřešil, tahle konstrukce mi funguje, zatím jsem nenarazil na problém. Možná konečné řešení..? :)

Brain.stop = true;
backgroundWorkerAI.CancelAsync();
while (backgroundWorkerAI.IsBusy)
{
    Application.DoEvents();
}
UpdateStatus("Vymýšlení tahu zastaveno.", Status.ok);
Brain.stop = false;
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Žádné DoEvents. Použijte samozřejmě CancelAsync a v průběhu výpočtu kontrolujte hodnotu CancellationPending. V případě že bude True, přerušte výpočet (Return nebo GoTo).

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nejsem si jistý, jestli je možné udělat to co mi píšeš(te).

Takhle: V události DoWork mám zavolání statické metody GetBestTurn třídy ComputerPlayer, metoda GetBestTurn vola statickou metodu BestTurn třídy Brain, takže proto myslím, že kontrolovat property CancellationPending neni možné... I když, teď jak to píšu, tak jsi uvědomuju, že jde o property, takže ta kontrola je možná. Takže tady je má myšlenková mapa, ktera je teď imho uplně zbytečná. Díky za radu :)

PS: GoTo fuuuuuj ;)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak bohužel, na instanci BackgroundWorkera z třídy Brain nevidím. Předávat "odkaz" na ni mi příjde jako zbytečné komplikování. V současnosti mi zámek funguje spolehlivě -> tak jak chci. Jakýmž takýmž testováním procházím i s tím, takže bych to nekomplikoval. Každopádně děkuji za nápad.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak přesuňte kód přímo do metody DoWork. Jiný způsob ukončování vlákna BackgroundWorkeru není správný. Mimochodem co máte proti GoTo? Zavrhovat GoTo je obvykle výsada kretenů z vysokých škol, kteří v praxi napsali tak maximálně konzolový Hello World. V určitých případech je GoTo nenahraditelná záležitost.

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Bohužel, kód nemohu přímo přesunou do metody DoWork; pokud bych kód přesunol přímo do DoWork, tak příjdu o odstínění logiky aplikace od jejího GUI a to je v rosporu se zadaním, to je bohužel přesně vymezeno, jinak by to bylo nejjednodužší řešení.

Ano, jsem kreten z vysoke skoly, v praxi jsem par programu napsal, určitě souhlasím, s goto lze vyřešit spoustu problemu, jde o rychle řešení, ale podle mého názoru je ale nepředvýdatelné, a špatně optimalozovatelné.

Nejsem na něj zvyklý, nepoužívám jej, vzdy jsem se mu mohl vyhnout. Ale technicke intormace o goto nemam, takže může být fajn.

Pokud máte nějaké informace o goto, nějaký užitečný odkaz s best-practies, kdy je fajn jej použít, budu rád, když se podělíte.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

K vašemu problému: V tom případě je tu ještě možnost použít vlastní vlákno uvnitř té třídy a synchronizaci s ovládacími prvky provádět pomocí WindowsFormsSynchronizationContext (tak to dělá i BackgroundWorker), na přerušení výpočtu mít nějakou metodu.

K problému GoTo: Je naprosto předvídatelné, neexistuje scénář kdybyste nevěděl co se stane, skákat jde pouze v rámci jedné metody, nikoliv kdekoliv v programu. Není na tom co optimalizovat, jedná se o zcela základní rutinu. Zatím nejlepší použití jsem našel u vyskočení z několika vnořených cyklů, které někteří chytráci řešili například zavedením proměnné Boolean a jeho periodickou kontrolou v každém cyklu...

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback