[ mmwlada @ 14.08.2006. 15:39 ] @
Ako imam neku moju klasu npr.

Code:

class Roba
{
  int robaID;
  string robaNaziv;
  bool promenjen;
...
}


kako da namestim da kada se promeni naziv robe, da se automatski promeni atribut promenjen na true?

Mislio sam da se tu koriste eventi (onChange), ali sam shvatio da ništa ne razumem; kako to radi?
[ NrmMyth @ 14.08.2006. 16:14 ] @
Exponiraj property ili funkciju
Code:
property string RobaNaziv
{
    set
    {
        robaNaziv = value;
        promjenjen = true;
    }
    get
    {
        return robaNaziv
    }
}

Mislim da ovako idu propertyi u C#.
[ mmix @ 14.08.2006. 17:40 ] @
Citat:
NrmMyth: Exponiraj property ili funkciju
...
Mislim da ovako idu propertyi u C#.


Slicno, samo jos jedan dodatak, ako je klasa dostupna multithreadingu, stvari moraju da se malo iskomplikuju vise posto je promena sad transakciona:

Code:

private string privRobaNaziv;
private bool privPromenjen;

public string RobaNaziv
{
    set
    {
        lock(this)
        {
            privPromenjen = privPromenjen && (privRobaNaziv != value);
            privRobaNaziv = value;
        }
    }
    get
    {
        lock(this) return privRobaNaziv;
    }
}

public bool Promenjen
{
    get
    {
        lock(this) return privPromenjen;
    }
}


treba ti naravno i mehanizam koji ce resetovati privPromenjen na false; to se obicno radi iz npr. Save() metoda koji uskladi sadrzaj tvoje klase sa npr Data layerom. Naravno sve zavisi zasto tebi treba taj flag uopste...


[ NrmMyth @ 16.08.2006. 00:43 ] @
Citat:
mmix: Slicno

“Exciplit is good.”
:)
[ mmwlada @ 16.08.2006. 11:10 ] @
Pa da. Uopšte mi nije palo na pamet da to odradim preko property-a. Sve vreme razmišljam na komplikovaniji način. Radi odlično. Hvala.
[ ebug @ 20.08.2006. 20:37 ] @
Interesantno rjesenje.

Ako moze samo malo logickog pojasnjenja....

Interesuje me zasto si radio lokove na geterima jer mi se cini da bi, u slucaju da puno tredova koji pristupaju objektu, ovakav kod mogao imati jak "Performance penalty" zbog zakljucavanja geter objekata i njihovog cekanja na seter da pusti svoj lok koji drzi ili obrnuto.

Cini mi se, da bi se, uslovno receno (jer se radi o loku na istu instancu), bolji concurrency dobio nekim Eventom a getere pustiti tredovima na citanje prema momentu pristupa. Na ovaj nacin bi "event subscriber" odlucio da li je zainteresovan za pracenje promjena na objektu ili ne. Sigurno da i ovaj pristup ima svoje mane jer bi u slucaju remotinga, ako je objekat Serializovan, "gubili" event kao mogucnost pracenja+br. podignutih evenata...itd.
[ mmix @ 21.08.2006. 15:11 ] @
Performance penalty je definitivno prisutan kod multi-threading aplikacija, tu nema nikakve sumnje, ali je sigurno bolji od pada aplikacije


Ok, sto se tice eventa, stvari uopste nisu tako jednostavne kao sto mislis, recimo nek imas deset threadova koji imaju pristup ovoj klasi:

1. Svih deset threadova mora da ima instancu klase koja ce pratiti ovaj objekat (Da bi odredjeeni metod tih objekata bio handler za event)

2. Ako jedan thread pozove set, taj set mora da "pozove" event i da u ukviru svog threada pozove svih deset event handlera, to povlaci za sobom potrebu da sve klase tih deset objekata budu multi-thread safe. I opet imas performance penalty da je thread koji menja promnljivu zakljucan dok ne pozove svih deset handlera

Svejedno moras da imas lock na get. Znam da to moze izgledati malo zbunjujuce zato sto je to prosto bool polje, ali resursi se stite u oba pravca bez obzira na velicinu. Razlog je sto moze da se desi da thread koji je u get ne uradi dobrovoljni release (kroz Sleep, process queue itd) i da bude prekinut nasilno i da se taj prekid obavi izmedju dve asemblerske instrukcije koje cine pristup zasticenom resursu, u tom slucaju je resurs u "nestabilnom" stanju i ako drugi thread obavi set dolazi do gadnih situacija. Iako je statisticka verovatnoca da se to desi mala, imajuci u obzir da prosecan PC vrti oko 500 threadova sa izmedju 5 i 20 hiljada promena threadova u sekundi, desava se a bagovi koji su posledica ovoga su veoma nepredvidivi i veoma teski za lociranje i nemoguci za debagovanje. Jedini nacin da to radi apsolutno sigurno bez lock je da budes apsolutno siguran da ce JIT prevesti ono sto je u lock{} kao JEDNU I SAMO JEDNU asemblersku instrukciju, a to je nemoguce tvrditi sa nekom sigurnoscu

Ceo taj koncept sa eventima je veoma user-unfriendly OnPropertyChange event model se koristi kad treba obavestiti drugi objekat da je doslo do premene u prvom ako je ta promena od vzanosti za drugi objekat (sto drugi objekat odlucuje time hoce li se zakaciti za event). Njegova potreba je bila da se promeni stanje istog objekta, praviti event i onda ga konzumirati u okviru istog objetka samo radi promene internog stanja, hmmm, nisam siguran ni da je to uopste moguce i ako jeste definitivno ne preporucujem.

Nemoj zazirati od lock-a . Deset threadova koji su u WAIT_STATE za isti mutex objekat je savim ok i dok ovo citas desilo se bar nekoliko hiljada puta u tvom PC-u u samom OS-u ili u drugim programima Vazno je samo da sadrzaj lock-a bude sto jednostavniji i da ne zavisi od drugih lockovanih resursa iz drugih klasa/objeakta da ne napravis deadlock situaciju za koju leka nema.
[ ebug @ 21.08.2006. 18:41 ] @
Hvala na pojasnjenju....

U potpunosti si u pravu i svaki argument stoji.

Ja sam pretpostavio idealnu situaciju u kojoj je atomicnost podatka zagarantovana jer se tredovi izvrsavaju kao sto je i zamisljeno. Medjutim, ponasanje tredova koji pristupaju objektu se mora posmatrati kao sto si ti naveo, jer bi svaka druga obrada podatka vodila narusavanju osnovnog principa atomicnosti podatka.
Ti si ovu atomicnost osigurao (u kodu koji si gore napisao) na najnizoj mogucoj jedinici(varijable programa) a sve te varijable (sa lock{...} naredbom), zajedno, obezbijedjuju atomicnost pri transakcionom ponasanju instance sto predstavlja i zeljeni rezultat a i osigurava tacnost podatka i stabilnost programa.
Ono sto se meni ucinilo pri citanju tvog koda je da bi pri nepazljivoj promjeni koda (redosljed citanja i setovanja varijabli) korisnik dobio deadlock, izgubio transakcijsku atomicnost i narusio integritet programa. Medjutim, dodati event u multithread program gdje je citanje(geteri) pretpostavljeno po fire-and-forget principu i jos pokusati obraditi takav podatak(EventHandler) bi bilo, najblaze receno, pogresno.

U nedostatku boljih rjesenja, "Preformance penalty" koji se trpi pri lokovima i "Context switching"-u tredova je definitivna preferenca u odnosu na netacan podatak i nestabilan program.

[ erkan @ 22.08.2006. 08:24 ] @
mala digresija,
cini mi se da bi trebalo stajati || umjesto &&
ili mi je nesto promaklo;
Dakle,
Code:

        lock(this)
        {
            privPromenjen = privPromenjen || (privRobaNaziv != value);
            privRobaNaziv = value;
        }
[ mmix @ 22.08.2006. 12:04 ] @
Citat:
erkan: mala digresija,
cini mi se da bi trebalo stajati || umjesto &&
ili mi je nesto promaklo;


Hmm, da, mora da bude OR operator da bi sacuvao prethodnu vrednost flega (True OR X = True), zasto li sam ja stavio && ne secam se, mora da je typo. Da je AND operator, fleg nikad ne bi postao true zato sto je pocetna vrednost flega False, a False AND X = False. Hvala za ispravku...