10 Ekim 2014 Cuma

InvokeRequired nedir?

En basit anlamıyla; Bir windows kontrolünün metoduna, kontrolün yaratıldığı threadin dışında başka bir thread üzerinden erişilmeye çalışıldığında, erişim için bir invoke methoduna ihtiyaç duyup duymadığını belirten bir değerdir.

Eğer kontrol başka bir thread üzerinde yaratılmışsa true döner aksi halde false döner.

Windows Forms ta kontroller belli bir thread'e bağlıdır ve thread safe değillerdir. (Hayda thread safe ne yahu?)
Thread Safe: Bir kaynağa veya fonksiyona herhangi bir zamanda sadece bir tek threadin erişimini garanti etmek gibi diyebiliriz. Bir banka hesabı düşünün ToplamPara adında bir değişkeni olsun ve bu değişkenin değeri 100 olsun. 2 kişi aynı anda bu banka hesabı üzerinde işlem yapıyor diyelim. Birinci kişi 100 lira para çekmeye çalışsın diğer kişide 100 lira para yatırmaya çalışsın. Her ikisi de aynı anda işlem yapmaya çalıştığı için ekranda 100 lira değerini görüyor. Eğer hesapta bulunan toplam para değerine erişimi bir hizaya dizmez ise birinci kişi 100 lira çektiğinde ToplamPara değişkeninin değerini 0 (ToplamPara - 100 = 0) olarak değiştirir . İkinci kişi ise bu değişkeni 200(ToplamPara + 100 = 200) olarak değiştirir. Sonuçta hesabın ToplamPara değeri 200 olur ama doğrusu 100 olmalıydı. İşte bunun olmaması için iki kişinin ToplamPara değişkenine aynı anda erişimini engellemeliyiz. İşte Windows forms kontrolleri bunu sağlamayı garanti etmediği için thread safe değillerdir.

InvokeRequired property'sine ek olarak thread safe olan 4 tane method bulunmaktadır. Bunlar: Invoke, BeginInvoke, EndInvoke and CreateGraphics metodlarıdır.

Eğer kontrolün handle'ı henüz oluşturulmamışsa InvokeRequired, window handle'ı elinde bulunduran form veya window'u bulana kadar kontrolün parentlarını aramaya başlar. Eğer bulamazsa false değeri döner.
Bunun anlamı, ya kontrolün methoduna erişmek için Invoke kullanmaya gerek yoktur (kontrolün metoduna kontrolün yaratıldığı threadden ulaşılmaya çalışılmaktadır.) ya da kontrol başka bir thread üzerinde yaratılmıştır ama kontrolün handle ı henüz oluşturulmamıştır. (Bir de böyle bişey var malesef!)
Böyle kontrolün handle'ının henüz oluşturulmadığı durumlarda kontrolün property,metod ve eventlerine ulaşmaya çalışmayınız. Çünkü siz ulaşmaya çalıştığınızda handle henüz yeni oluşturuluyor olabilir.
Böyle durumlarda IsHandleCreated propertysinide kontrol etmeniz gerekmektedir. Handle henüz yaratılmamışsa, Invoke ya da BeginInvoke methodunu handle yaratılana kadar çağırmayınız. Bu senaryo çok fazla karşınıza çıkmaz eğer background threadi formun constructorunda oluşturmuyorsanız ya da yada formu göstermeden önce çağırmıyorsanız.

Bunun çözümü ya handle yaratılana kadar bekleyeceksiniz ya da Handle propertysini çağırarak zorla yaratılmasını sağlayacaksınız.

Umarım InvokeRequired nedir, anlayabilmiş ve anlatabilmişimdir.