VB.NET: BackgroundWorker Control


Control BackgroundWorker menjalankan code dibelakang layar, tanpa mempengaruhi form yang mengeksekusi perintah. Sering dipakai untuk proses import/export data atau eksekusi code lain yang membutuhkan waktu lama. Setelah beres eksekusi code, BackgroundWorker akan mengembalikan hasil nya ke form.

BackgroundWorker ada di Toolbox-> All Windows Form, seperti pada gambar berikut:

Untuk lebih jelas tentang penggunaan control ini, mari kita buat aplikasi dengan loop (putaran) yang memakan waktu cukup lama sebagai berikut:

UI:
BackgroundWorker tidak akan ditampilkan di form melaikan di bagian bawah (area abu-abu). Tambahkan sebuah textbox untuk menampilkan "putaran ke-", button 1 untuk memulai putaran, dan button 2 untuk cancel proses. Kita juga menambahkan progress bar.

Code:
Keterangan kode pada comment berwarna hijau.

Imports System.ComponentModel

Public Class Form1

 Dim iMax As Integer = 200 'iterasi maksimal

 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
    'untuk mencegah error saat background proses mengubah UI
    Control.CheckForIllegalCrossThreadCalls = False

    With BackgroundWorker1
        .WorkerReportsProgress = True 'catat nilai progress
        .WorkerSupportsCancellation = True 'supaya bisa cancel
    End With

    'setting nilai maksimum progress bar
    ProgressBar1.Maximum = iMax

    'UI Teks untuk button
    Button1.Text = "Start"
    Button2.Text = "Cancel"
 End Sub

 Private Sub Button1_Click(sender As Object, e
As EventArgs) _
         Handles Button1.Click
    'Menjalankan proses background
    BackgroundWorker1.RunWorkerAsync()
 End Sub

 Private Sub Button2_Click(sender As Object, e
As EventArgs) _
         Handles Button2.Click
    'Membatalkan proses background
    BackgroundWorker1.CancelAsync()
    BackgroundWorker1.Dispose()
 End Sub

 Private Sub BackgroundWorker1_DoWork(sender As Object, _
             e As System.ComponentModel.DoWorkEventArgs) _

             Handles BackgroundWorker1.DoWork
    'mulai iterasi
    For i = 0 To iMax
        'handle jika ada cancel
        If BackgroundWorker1.CancellationPending = True Then
            e.Cancel = True
            Exit For
        Else

            'proses normal tanpa cancel
            TextBox1.Text = i 'menampilkan iterasi ke pada textbox
            'mengirim progress iterasi
            BackgroundWorker1.ReportProgress(i)
            'supaya proses berhenti sejenak 1000 milidetik = 1 detik
            System.Threading.Thread.Sleep(1000)
        End If
    Next
 End Sub


 Private Sub BackgroundWorker1_ProgressChanged(sender As Object, _
            e As ProgressChangedEventArgs) _

            Handles BackgroundWorker1.ProgressChanged
    ProgressBar1.Value = e.ProgressPercentage
 End Sub

 Private Sub
BackgroundWorker1_RunWorkerCompleted(sender As Object, _
            e As RunWorkerCompletedEventArgs) _

            Handles BackgroundWorker1.RunWorkerCompleted
    If e.Cancelled = True Then
        MsgBox("Proses Dibatalkan")
    Else
        MsgBox("Proses Selesai")
    End If

 End Sub

End Class


Runtime:
Jalankan program dan klik tombol Start.

Jika saat proses berjalan kita klik tombol cancel maka proses akan berhenti dan muncul pesan berikut:

Sementara jika kita biarkan sampai proses selesai, akan muncul pesan berikut.


Click here if you like this article.


Post a Comment

8 Comments

Bernard Yunanto said…
Assalamu’alaikum Warahmatullahi Wabarakaatuh
mbak rani saya mohon bantuannya.
bagaimana cara memberi progress bar disaat kita sedang meng export datagridview ke excel ?
dan form tidak bisa di ketik bila proses export belum selesai.
atas bantuannya saya ucapkan terimakasih.
rani said…
Wa alaikum salam warahmatullahi wabarakaatuh

progress bar bisa di selipin di proses looping saat export ke excel.
Tergantung gimana cara export excel nya, klo mirip2 sama di artikel ini:
https://rani-irsan.blogspot.com/2016/01/vbnet-mysql-export-data-ke-excel.html

rani kasih clue nya aja ya:
sebelum looping set nilai progress bar maksimum, sesuai jumlah data yang di export (dikurangi 1 karena mulai dari 0)
ProgressBar1.Maximum = grdData.RowCount - 1

Mulai memberi nilai dari 0
ProgressBar1.Value = 0

Nilai maksimum ini bukan pakem, bisa ditambahkan klo ingin proses sebelum dan sesudah nya dimasukan tahapan juga.
Misalnya saat generate nama kolom dihitung 1 tahap maka tambahkan 1 lagi ke property ProgressBar1.Maximum

Misalnya jadi:
ProgressBar1.Maximum = grdData.RowCount

(-1 nya hilang karena nilai ditambah 1)

Dan setiap tahapan proses update nilai progress bar ProgressBar1.Value

Lanjut update ProgressBar1.Value saat looping:
For r = 0 To grdData.RowCount - 1
For i As Integer = 1 To grdData.Columns.Count
ApExcel.Cells(r + 2, i).Value = grdData.Rows(r).Cells(i - 1).Value
Next
ProgressBar1.Value = CInt(ProgressBar1.Value) + 1
Next

Simpan di event BackgroundWorker klo pengen jalan di belakang layar (biar app nya ga "not responding")

Supaya ga bisa diketik atau di klik, form nya enabled = false sebelum proses export dan balikin ke True saat udah selesai.

Semoga sedikit ada pencerahan.

Happy Coding!
Bernard Yunanto said…
Terimakasih atas bantuannya,mbak. semoga mbak dan sekeluarga selalu dalam lindunganNYA dan selalu mendapatkan rezeki. Aamiin
Unknown said…
Dari sekian bnyak berburu blog ttg bgworker, baru kali ini dpt pencerahan knp gak bs forced UI. masalah kelar. makasih banyak mbak. semoga berkah. salam dari bali
Unknown said…
apakah ini berlaku disaat meyimpan data ke database
rani said…
ya, biasanya pakai ini untuk proses yang membutuhkan waktu lama, seperti saving ke database atau proses upload...
AndrieST said…
Thank you mbak, step stepnya mudah dimengerti