Thursday, February 21, 2013

Back to the w*ndow$ free version (red:bajakan)

Kembali ke windows dengan beberapa bayangan dan perbandingan pemrograman yang telah dipelajari di linux khususnya java, saat ini ingin menerapkan beberapa methode yang sering dipakai sebelumnya. Hal pertama yang terbersit dalam pikiran saya adalah tentang multithreading. Bagaimana pemrograman multithreading di windows? Bagaimana mengakses GUI dari thread yang terbentuk dari kelas yang berbeda? Kira-kira seperti itu pertanyaan yang muncul di pikiran saya. Hemmm... mungkin sama seperti di java yang bisa dilakukan dengan merubah modifier komponen form menjadi public dan static. Dengan berbekal pertanyaan dan asumsi tersebut saya mencoba mencari jawaban dengan googling ke sana kemari dan tentu membawa hasil yang memuaskan karena google adalah simbah saya :D.

Untuk menerapkan apa yang telah saya dapat, langsung saja kubuka visual studio free version (red:bajakan lagi). Program yang dibuat ini merupakan kompilasi source dari sana sini. Mulai dengan new project dan memilih C# kemudian WindowsFormApplication. Desain form seperti berikut :


Form dibuat demikian karena saya berencana membuat sebuah thread yang akan menghasilkan log pada textbox. Log yang akan ditampilkan merupakan list dari file yang ada di dalam direktori. Ya fungsi searching file yang dilakukan secara recursif. 

Pada start button dilakukan pembuatan sebuah thread dari fungsi searcing file tersebut.

        private void Start_Click(object sender, EventArgs e)
        {
            ThreadStart soto = delegate
            {
                SearchDir("D:\\");
            };
            tr = new Thread(soto);
            tr.Start();
            this.Start.Enabled = false;
        }

Thread ini merupakan perwakilan (:D) dari fungsi di bawah ini :

        public void SearchDir(string path)
        {
            SearchFile(path);
            string[] fol = Directory.GetDirectories(path);
            for (int i = 0; i < fol.Length; i++)
            {
                    _pauseEvent.WaitOne(Timeout.Infinite);

                if (_shutdownEvent.WaitOne(0))
                    break;
                    SearchDir(fol[i]);
                }
        }

        public void SearchFile(string dir)
        {
            string[] file = Directory.GetFiles(dir);
            for (int i = 0; i < file.Length;i++)
            {
                if (this.textBox1.InvokeRequired)
                {
                    this.textBox1.Invoke((MethodInvoker)delegate()
                    {
                        this.textBox1.Text = this.textBox1.Text + "\r\n" + file[i];
                        this.textBox1.SelectionStart = this.textBox1.Text.Length;
                        this.textBox1.ScrollToCaret();
                        this.textBox1.Refresh();
                    });
                }
            }
        }

Terlihat jelas ada perbedaan cara pengaksesan komponen GUI dari sebuah thread (berbeda cara saya mengakses). Di sini diperlukan method invoker untuk mengakses komponen. Ketika program running tampilan GUI akan seperti berikut:



Saat program run, ada dua tombol yang masih aktif untuk mengontrol jalanya thread. Berikut kode pada tombol pause :

        private void Pause_Click(object sender, EventArgs e)
        {
            if (this.Pause.Text == "Pause")
            {
                _pauseEvent.Reset();
                this.Pause.Text = "Resume";
            }
            else
            {
                _pauseEvent.Set();
                this.Pause.Text = "Pause";
            }
        }

Ketika tombol pause ini ditekan maka thread akan dalam posisi pause dan tulisan tombol menjadi "Resume", ketika ditekan sekali lagi thread akan melanjutkan dan tulisan tombol kembali menjadi "Pause".




Kemudian tombol stop yang berfungsi untuk menghentikan semua kegiatan thread, seperti ini kode programnya.

        private void Stop_Click(object sender, EventArgs e)
        {
            try
            {
                tr.Abort();
            }
            catch { }
        }

Kegiatan program berhenti sampai di sini. Untuk mengontrol banyak thread saya telah memiliki bayangan yaitu dengan membuat sebuah collection list yang berisi objek dari thread yang telah terbuat. Mungkin penerapan saja yang belum sempat terpikirkan. Semoga sedikit bacaan ini bisa berguna suatu saat nanti. :)