Aklımda Kalası Kelimeler

* давайте работать вместе
* Zarf ve Mazruf, Zerafet(xHoyratlık) ile aynı kökten(za-ra-fe) gelir
* Bedesten
* Suç subuta ermiştir - Suç sabit olmuştur
Delegate etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Delegate etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

1 Nisan 2011 Cuma

C# Delegate

Önce aşağıdaki ekran çıktısına bakarak neler çıkarabildiğimize bakalım:
  1. System isim uzayında (System.Delegate)
  2. ICloneable arayüzünü implement etmiş. Demek ki public object Clone() imzalı bir metodu implement etmiş.İlk metot olan Clone() ICloneable arayüzünden geliyor
  3. ISerializable arayüzünü implement etmiş. Demek ki kendine has bir serileştirme yapısı kurulmak istenmiş.

İsimsiz metotlar C# 2.0 ile gelmiş, delegate ile kullanılabiliyorlardı. Delegate, fonksiyon işaretçisi olarak kullanmamız için önemli bir araç. Delegate türünde yeni bir tür tanımlayarak, bu türümüzün örneklerine metotları değer olarak verebiliyoruz. Bu sayede bu fonksiyon işaretçilerimizi herhangi bir zaman çağırabiliriz.

Bir metodun dönüş türü ya void ya da belirli bir tipte örneği olabilir. Void dönüşlü metotlar için C# 3.0 ile gelen Action'ı kullanabiliriz(void dönüşlü metotlar için olup parametre listesini generic verebiliriz Action<int,bool,OyuncuSinifi>).
Bir de dönüş türü bir tipin örneği olacak metodlar için Func'ı kullanabiliriz. Buraya kadar her şey yolunda değil mi?

using System;
using System.IO;

namespace CSharp_Orneklerim.Delegate_Event
{
    /*
     *  delegate Bir tip tanımlamasıdır, değişken deklarasyonu değildir. 
     *  Hiçbir tip tanımlaması metot içinde tanımlanmaya müsade edilmez. 
     *  Tip tanımlamaları sadece sınıf(class) ve isim uzayı kapsamında yapılabilir
     */

    partial class Delegate_01
    {
        static void Calis()
        {
            // 1. Kısımda DELEGATE nasıl çalışır
            Birinci_Kisim();

            // 2. Kısımda COvariance ve CONTRAvariance örneği olacak
            Ikinci_Kisim();

            // 3. Kısımda lambda ifadeleriyle delegate tanımlanması
            Ucuncu_Kisim();

            // 4. Kısımda Action ve Func tanımlamalarıyla delegate tanımlanması
            Dorduncu_Kisim();

            // 5. Kısımda delegate tiplerin GENERIC hallerini yazalım
            Besinci_Kisim();
        }


        #region *********************** 1. KISIM - DELEGATE Nasıl Çalışır? *******
        // Önce bir delegate tanımlayacağız(Tıpkı sınıf tanımladığımız gibi). 
        // delegate'imizin adı DelegateTipi olacak(tıpkı Kisi adında class tanımlar gibi). 
        // Void dönecek ve parametre almayacak(tıpkı property, field, metotlar tanımladığımız classlar gibi)
        public delegate void DelegateTipi();
        private static void Birinci_Kisim()
        {
            // Yukarıda tanımladığımız DelegateTipi'nden f örneğini(tıpkı cenkGonen nesnesini Oyuncu sınıfından türetir gibi) tanımlayalım.
            // f nesnemize(Delegate tipi referans tiptir)
            // A delegate is a reference type that can be used to encapsulate a named or an anonymous method.
            DelegateTipi f = null;
            DelegateTipi f1 = null;
            f1 = delegate { Console.WriteLine("f1 yaz bişi"); };
            f1 += delegate { Console.WriteLine("f1 yaz bişi daha"); };

            f += delegate { Console.WriteLine("bu da yaz"); };
            f += f1;
            Console.WriteLine(f.GetInvocationList().Length);
            f -= (DelegateTipi)f1.GetInvocationList()[1];
            Console.WriteLine(f.GetInvocationList().Length);
            f();


            //--------------------------------- STATIC tip olarak Delegate tanımlama --------------------------------------
            // STATIC_VAR:
            // 
            // TekParametreliIntDonuslu tipini tanımlıyoruz
            // static TekParametreliIntDonuslu static_delegate_degisken : ile sınıfa bağlı bir field tanımlıyoruz
            // ve hemen aşağıdaki satırlarda bir metodu bu değişkene değer olarak atayıp delegate üstünden metodu ateşliyoruz.
            Delegate_01.static_delegate_degisken = new TekParametreliIntDonuslu(delegate(int a) { return a += 1; });
            Delegate_01.static_delegate_degisken(3); // 4 dönecektir
        }
        // STATIC değişken olarak deklare edeceğimiz değişkenin türetileceği tip olan delegate tanımlaması
        public delegate int TekParametreliIntDonuslu(int _i);
        // delegate tipler static tanımlanamaz ancak delegate tipten static bir değişken tanımlanabilir (STATIC_VAR)
        public static TekParametreliIntDonuslu static_delegate_degisken;

        // Hatta delegate tiplerinin get ve set metotları olabildiği için property olarak da tanımlayabiliyoruz ***
        public DelegateTipi budaPropertyOlsun { get; set; }
        #endregion

        #region *********************** 2. KISIM - CO-CONTRA_variance ************
        // delegate nesneleri, delegate'in imzasındaki dönüş tipinden türeyen nesneleri döndüren metotları işaret ederse
        public delegate Stream Delegate_Covariance_tipi();

        // delegate nesneleri, delegate'in imzasındaki parametrelerin türeyen nesnelerini parametre olarak alan metotları işaret ederse
        public delegate void Delegate_Contravariance_tipi(StreamWriter _sw);
        private static void Ikinci_Kisim()
        {
            // Metodumuz FileStream(Stream'den türemiş), TextReader parametresi aldığı için
            // Covariance delegate kullanılmış diyebiliriz
            Delegate_Covariance_tipi del_co = delegate()
                                                        {
                                                            // Dönüş nesnesi de Stream sayılır ;)
                                                            return new FileStream("dosyaYolu.txt", FileMode.OpenOrCreate);
                                                        };

            // f_contra metodu TextWriter türünden alıyor. Bu da StreamWriter'da türetildiği için contravariance oluyor
            Delegate_Contravariance_tipi del_contra = f_contra;
        }

        static void f_contra(TextWriter tw) { }
        #endregion

        #region *********************** 3. KISIM - LAMBA EXPRESSIONS *************

        public delegate void Del_Donussuz_Parametreli(int _a, byte _b);
        public delegate TextWriter Del_DonusTipli_Parametreli(string _dosyaYolu);
        private static void Ucuncu_Kisim()
        {
            //----------------------- DÖNÜŞSÜZ(void)
            // İsimsiz fonksiyon olarak delegate ile şöyle yazılır:
            Del_Donussuz_Parametreli delegate1 = delegate(int a, byte b)
                                               {
                                                   Console.WriteLine("Ben dönüşsüz bir metodum");
                                                   Console.WriteLine("{0} ve {1} değerinde 2parametre aldım", a, b);
                                               };

            // Lambda ifadesiyle şöyle yazılır:
            Del_Donussuz_Parametreli lambda1 = (a, b) =>
                                               {
                                                   Console.WriteLine("Ben dönüşsüz bir metodum");
                                                   Console.WriteLine("{0} ve {1} değerinde 2parametre aldım", a, b);
                                               };

            //----------------------- DÖNÜŞLÜ

            // İsimsiz fonksiyon olarak delegate ile şöyle yazılır:
            Del_DonusTipli_Parametreli delegate2 = delegate(string dosyaAdresi)
                                                   {
                                                       TextWriter tw = File.CreateText(dosyaAdresi);
                                                       return tw;
                                                   };

            // Lambda ifadesiyle şöyle yazılır:
            // Tek parametre olduğu için parantez içine almaya gerek yok "_dosyaninAdresi" parametresini
            Del_DonusTipli_Parametreli lambda2 = _dosyaninAdresi =>
                                                 {
                                                     // Parametreyi kullanmadık ama StreamWriter türünde bir nesne dönmeden edemeyeceğim
                                                     TextWriter tw = Console.Out;
                                                     tw.WriteLine("Ekrana gitmeden merhaba diyeyim");
                                                     return tw;
                                                 };
        }
        #endregion

        #region *********************** 4. KISIM - Action & Func *****************
        private static void Dorduncu_Kisim()
        {
            //----------------------- DÖNÜŞSÜZ (void)
            /* Action ve Func zaten Delegate'ten türetilmiş oldukları için 
             * Action ya da Func tipinden bir nesne yaratmak 
             * Delegate tipinde bir nesne yaratmakla aynı anlama geliyor.
             */
            Action<int, byte> donussuz_2_parametreli_metot = delegate(int a, byte b)
                                                        {
                                                            Console.WriteLine("Dönüşsüz demiştik. Parametreler:");
                                                            Console.WriteLine("{0} ile {1} değerlerini içeriyor", a, b);
                                                        };
            // Doğrudan örnek türettiğimiz bir tip tanımı olarak kullandık Action'ı
            donussuz_2_parametreli_metot(1, 2);

            // Başka bir Action'a atayabiliriz
            Action<int, byte> donussuz_parametreli_metod = new Action<int, byte>(donussuz_2_parametreli_metot);
            donussuz_parametreli_metod(3, 4);

            // delegate ile sınıf veya namespace kapsamında tip oluşturmadan, 
            // void dönen metodu doğrudan nesne yaratarak çağırmak için 
            // delegate(){} kısmını Action<>(...) içine alıyoruz.
            Action<int, byte> tip_olusturmadan_delegate_ile_donussuz_metot_tanimlamak = new Action<int, byte>(delegate(int a, byte b) { });

            //*********** DÖNÜŞLÜ
            // delegate ile sınıf veya namespace kapsamında tip oluşturmadan, 
            // değer dönen metodu doğrudan nesne yaratarak çağırmak için 
            // delegate(){} kısmını Func<>(...) içine alıyoruz.
            Func<int, string> tip_olusturmadan_delegate_ile_metot_yazmak = new Func<int, string>(delegate(int a) { return a.ToString(); });
            tip_olusturmadan_delegate_ile_metot_yazmak(211);

            // Func<int,string> : int tipinde 1 parametre alıyor string dönüyor
            // tek parametreyi paranteze sarmaya gerek yok
            // birden çok satırda işlem yapmadığı için gövdeyi {...} sarmaya da gerek yok
            Func<int, string> string_donuslu_int_parametreli = i => i.ToString();
            string_donuslu_int_parametreli(114); // 114 yazacak ekrana
        }

        #endregion

        #region *********************** 5. KISIM - Generic Delegates *************

        public delegate S jenerikFunc<T, K, S>(T t, K k);
        public delegate void jenerikAction<T, K>(T t, K k);
        private static void Besinci_Kisim()
        {
            jenerikFunc<int, byte, string> jenerikFuncNesnesi = (i, b) => (i + b).ToString();
            string toplam = jenerikFuncNesnesi(3, 4);// toplam = "7" 

            jenerikAction<int,byte> jenerikActionNesnesi = delegate(int i, byte b)
                                                           {
                                                               Console.WriteLine("dönüşsüz metot!");
                                                               Console.WriteLine(i+b);
                                                           };
            jenerikActionNesnesi(4, 5);// Ekrana iki satır yazacak > 
            // 1. satır: "dönüşsüz metot!", 
            // 2. satır: "9"
        }
        #endregion
    }
}

Action

Action ve Func makalesi için buraya tıklayabilirsiniz

Func

4 Mart 2011 Cuma

Çeşitli Thread yöntemleri


private void btnUpdate_Click(object sender, EventArgs e)
{
if (pc != null)
{
Commander cmd = new Commander(pc);

new Thread(new ThreadStart(delegate()
{
int i = pc.ToplamOkunacakByte;
MessageBox.Show(i.ToString());
})).Start();

// pc formun SerialPort okuma işini yapan objeyi barındıran sınıfının örneği
new Thread(new ThreadStart(() =>
{
int i = pc.ToplamOkunacakByte;
MessageBox.Show(i.ToString());
})).Start();

// pb form üzerindeki ProgresBar dır (private System.Windows.Forms.ProgressBar pb;)
pb.Maximum = 100;
pb.Value = 0;

// Thread e parametre olarak pb yi veriyor,
// delegesinde ise p olarak kullanıyoruz.
new Thread(new ParameterizedThreadStart((p) =>
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(10);
((ProgressBar)p).Value++;
}
})).Start(pb);
}
}


26 Kasım 2009 Perşembe

Form harici bir sınıftan formun kontrollerine erişmek


using System;
using System.Threading;
using System.Windows.Forms;
/**
* Invoke metodu ne iş yapar?
* Invoke işlemi bir thread içinde işlem yaparken başka threaddeki bir control üzerinde işlem yapmamızı sağlar.
* Invoke metodunu kullanmadan bu control'e erişmeye kalkarsak
* "Cross-thread operation not valid"
* gibi bir mesaj alırız.
*
* Eğer runtime da ekledigimiz controller varsa ve thread içerisinde onlara erişmemiz gerekiyorsa
* invoke ve delegate kullanarak bunu yapabiliriz.
**/
namespace waForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private delegate void DelFormCalisirkenBizimMetodaErismemizeYardimciOlacakMetotReferansi();

private void button1_Click(object sender, EventArgs e)
{
FormHariciSinif mt = new FormHariciSinif();

DelFormCalisirkenBizimMetodaErismemizeYardimciOlacakMetotReferansi yardimciOlacakMetotReferansi
= new DelFormCalisirkenBizimMetodaErismemizeYardimciOlacakMetotReferansi(mt.f_CalistirmakIstedigimizMetot);

/**
* Formun çalışmasından farklı olarak (Bunun main thread, ilk iş parçacığımız olduğunu unutmayalım)
* Calismasini istediğimiz
* "FormHariciSinif"
* sınıftan türetilen bir objenin
*
* "f_CalistirmakIstedigimizMetot"
* metodu bulunuyor.(Bununda ikinci iş parçacığı olacağını unutmayalım)
*
* Ama metodumuz formun dışında bir sınıfın objesine ait olacağı ve her işlemin sonunda Form daki btn isimli button
* kontrolüne erişeceği için thread ler arası(iş parçacıkları arası) bir iletişime ihtiyacımız var.
**/

// Metodun sonunda, f_InvocationBitti metodu çalışsın
yardimciOlacakMetotReferansi.BeginInvoke(f_InvocationBitti, null);
}

private void f_InvocationBitti(IAsyncResult _ar)
{
if (_ar.IsCompleted)
{
MessageBox.Show("bitti");
}
}
}

public class FormHariciSinif
{
public void f_CalistirmakIstedigimizMetot()
{
Form frm = Form.ActiveForm as Form1;
Button btn = (Button) frm.Controls.Find("btn", true)[0];
for (int i = 0; i < 10; i++)
{
if (btn.InvokeRequired) // btn nesnesine başvuru farklı iş parçacığından mı? yani invoke gerekli mi?
{ // Gerekiyorsa, yeniden bir metodun referansına Invoke ile gideriz.
btn.Invoke(new MethodInvoker(delegate
{
btn.Text = i.ToString();
}));
}

Thread.Sleep(250); // Çalıştığını görelim diye.
}

/** for döngüsünden çıkınca da çalışsın diye buraya konulabilirdi ama
* biz, BeginInvoke(fBitinceCalisacakFonk,null) diye yazdık.

if (btn.InvokeRequired)
{
btn.Invoke(new MethodInvoker(delegate
{
MessageBox.Show("bitti");
}));
}
* */
}
}
}



16 Ekim 2009 Cuma

Delegate ile Thread yaklaşımı.

Sözün Özü
Çünkü bu konuda çok örnek var. Ben sadece iki çok az daha farklı metot ile anlaşılırlığı birazcık daha arttırmak istedim. Ama esas vurgum en alttaki nota olacak. "this.InvokeRequired" herhangi bir delegate (beginInvoke) ile çağırıldığında TRUE olarak set ediliyor. Yani listbox1.InvokeRequired ya da button1.InvokeRequired doğrudan Main Thread den başka bir threade geçilmek isteniyor mu (BeginInvoke call edilmiş mi?) diye bakar. this.InvokeRequired, listbox1.InvokeRequired ya da button1.InvokeRequired ile de geçişi yakalayabilirsiniz.

Olayımız Nedir?

Butonumuz kırmızı ve gri olacak Timer1 nesnemizle her 3 saniyede. Bu arada thread bir for içinde dönecek 1000000... gibi bir sayıya ulaşıncaya kadar listBox1 içine item ekleyeceğiz.
Sonuç aşağıdaki gibi olacak:

Bunu aşağıdaki kodla yapabiliyoruz:


Aşağıdaki kodla da yapabiliyoruz:


NOT:
InvokeRequired required compares the thread ID of the calling
thread to the thread ID of the creating thread.

If these threads are different,it returns true.



namespace wfDelegate
{
public partial class Form1 : Form
{
private delegate void DelYeni();
private DelYeni delYeniBeginInvoke;

private delegate void DelSayListeyeEkle();
private DelSayListeyeEkle delSayEkle;


public Form1()
{
delYeniBeginInvoke = new DelYeni(YeniDelegate);
delSayEkle = new DelSayListeyeEkle(SayListeyeEkle);
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
delSayEkle.BeginInvoke(null, null);
}

void SayListeyeEkle()
{
for (int i = 0; i < 1000000000000; i++)
{
ListeyeEkle(i);
}
}

private bool b;
private void ListeyeEkle(object item)
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(
delegate
{
b = this.InvokeRequired;
delYeniBeginInvoke.BeginInvoke(null, null);
listBox1.Items.Add(item);
}));
}
}


void YeniDelegate()
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(
delegate
{
button1.Width = 250;
}));
}
}

private void timer1_Tick(object sender, EventArgs e)
{
if (button1.BackColor == Color.Red)
button1.BackColor = Color.DimGray;
else
button1.BackColor = Color.Red;
}
}
}