Hướng dẫn sử dụng BackgroundWorker để xây dựng chức năng Chạy nền trong C#

Để hỗ trợ lập trình viên phát triển các chức năng đa tiến trình, tiến trình chạy song song (chạy nhiều tác vụ cùng một lúc mà không phải đợi tiến trình trước hoàn tất) C# đã cung cấp cho bạn lớp Thread trong namspace System.Threading. Tuy nhiên, chắc chắn rằng việc sử dụng Thread đòi hỏi bạn phải có những kiến thức cũng như kiến thức nhất định để có thể xử lý. Đó là nói về Threading.

Trong bài viết này mình sẽ chia sẻ cùng bạn về BackgroundWorker một component trong System.ComponentModel. Đây là lớp được .Net tích hợp nhằm giúp lập trình viên xây dựng, quản lý các tiến trình chạy nền trong ứng dụng dễ dàng hơn và hiệu xuất tốt hơn, dễ dàng hơn so với việc sử dụng Thread.


Hiện tại BackgroundWorker (.Net 4.0 là phiên bản sử dụng trong code mẫu) thì lớp này được cung cấp các thuộc tính sau:

Các thuộc tính chủ yếu class BackgroundWorker

WorkerReportsProgress : mặc định là False. Thuộc tính này nếu là True thì event ProgressChanged sẽ được thực thi (trong này bạn xử lý để hiển thị tiến độ công việc như thanh xử lý tiến trình, % tiến trình).
WorkerSupportsCancellation : mặc định là False. Thuộc tính này nếu là True thì thao tác ngừng tiến trình có hiệu lực.
CancellationPending : biến bool tiếp nhận trạng thái dừng tiến trình. Nếu giá trị là True tức là tiến trình được yêu cầu dừng.
IsBusy: biến bool tiếp ghi nhận trạng thái hoạt động của BackgroundWorker, mặc định là False. Nếu kiểm tra (!IsBusy) thì tức là tiến trình đang bận xử lý.

Các sự kiện chính class BackgroundWorker

DoWork: các thao tác xử lý công việc (lấy dữ liệu, tìm kiếm, update…) được diễn ra tại đây.
ProgressChanged: các xử lý hiển thị thông báo tiến độ của tiến trình đặt ở đây.
RunWorkerCompleted: các xử lý khi tiến trình hoàn tất hoặc bị ngừng bởi người dùng.

Ứng dụng mẫu sử dụng BackgroundWorker

Mình xây dựng 1 ứng dụng đơn giản chạy 1 vòng lặp for để hiển thị lên TextBox lần lượt chuỗi nội dung từ 0->n và sử dụng class BackgroundWorker để chạy, tạm dừng, chạy tiếp và dừng các tiến trình dưới nền. Nếu bạn quan tâm đến video hướng dẫn thì có thể xem thêm video sau:

Bước 1: Đầu tiên bạn tạo 1 dự án với các Controls như sau:

Hướng dẫn sử dụng BackgroundWorker để xây dựng chức năng Chạy nền trong CSharp
Hướng dẫn sử dụng BackgroundWorker để xây dựng chức năng Chạy nền trong C#

Bước 2: Mã xử lý trong quá trình khởi tạo Form như sau:

Cài đặt, xây dựng, thiết kế web/blog cá nhân, web affiliate, plugins, chrome extension và code tool theo yêu cầu.

public Form1()
{
            InitializeComponent();
            backgroundWorker1=new BackgroundWorker();
            backgroundWorker1.WorkerReportsProgress=true;
            backgroundWorker1.WorkerSupportsCancellation = true;
            //Đăng ký các event cho backgroundWorker1;
            backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}

Bước 3: Hàm xử lý tiến trình, trong hàm này các bạn đặt các thao tác xử lý của mình vào đây nhé, ở đây mình đặt thao tác xử lý vòng for cho phép hiển thị chuỗi tương ứng với chỉ số i:

private int demQuaTrinhXuLyDangChay = 0;
private void hamChuaCacThaoTacXuLyBangDoWorkBackground(DoWorkEventArgs e)
{
    for (Int64 i = Convert.ToInt64(txtChayTu.Text.Trim()); i < Convert.ToInt64(txtChayDen.Text.Trim()); i++)
    {
        //Đoạn này để chỉnh thời gian tạm ngừng giữa mỗi lần lặp của vòng for (lần xử lý);
        //Giá trị Sleep tính như sau 1000 = 1 giây;
        Thread.Sleep(Convert.ToInt16(txtThoiGianTamNgungGiuaCacLanXuLy.Text));
        //Kiểm tra trạng thái backgroundWork nếu bị ngừng thì dừng xử lý;
        if (backgroundWorker1.CancellationPending)
        {
            e.Cancel = true;
            return;
        }
        //Đoạn này để gọi event ReportProgress trong quá trình xử lý lần lặp i;
        //Ở đây mình đơn giản chỉ chạy dòng chữ ... cứ vậy cho đến khi xử lý hoàn tất thì hiển thị thông báo;
        demQuaTrinhXuLyDangChay++;
        backgroundWorker1.ReportProgress(demQuaTrinhXuLyDangChay);
        txtKetQuaXuLyTienTrinh.Text += i + ": [" + demQuaTrinhXuLyDangChay + "] lần xử lý "+i+" hoàn tất !\r\n";
        //Đoạn này để hiển thị tiến trình đang xử lý đến lần lặp i;
        txtKetQuaXuLyTienTrinh.SelectionStart = txtKetQuaXuLyTienTrinh.Text.Length;
        txtKetQuaXuLyTienTrinh.ScrollToCaret();
    }
}

Bước 4: Bạn viết mã xử lý cho các hàm sự kiện backgroundWorker1 như sau:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    //Gọi hàm xử lý tiến trình trong sự kiện DoWork;
    hamChuaCacThaoTacXuLyBangDoWorkBackground(e);
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    lblQuaTrinhXuLyTienTrinhHienTai.Text += ".";
    //Nếu label có hơn 3 dấu chấm thì gán lại giá trị rỗng cho thuộc tính Text;
    //Quá trình này sẽ được lặp lại cho đến khi tiến trình hoàn tất;
    //Bạn có thể sử dụng hình ảnh thể hiện dạng (loading...), đang xử lý để hiển thị cho người dùng biết;
    if (lblQuaTrinhXuLyTienTrinhHienTai.Text.Length >= 4)
    {
        lblQuaTrinhXuLyTienTrinhHienTai.Text = string.Empty;
    }
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        MessageBox.Show("Tiến trình xử lý được kết thúc bởi người dùng !", "Thông báo");
    }
    else
    {
        MessageBox.Show("Tiến trình xử lý hoàn tất !", "Thông báo");
        lblQuaTrinhXuLyTienTrinhHienTai.Text = string.Empty;
    }
}

Bước 5: Bạn viết mã xử lý sự kiện Click cho nút Chạy và Ngừng như sau:

private void btnChayTienTrinhXuLy_Click(object sender, EventArgs e)
{
    //Nếu backgroundWorker1 đang không trong quá trình xử lý thì chạy nó để bắt đầu xử lý;
    if(!backgroundWorker1.IsBusy)
    {
        backgroundWorker1.RunWorkerAsync();
    }
    //....
    //Bạn có thể viết mã hành xử thêm ở đây nếu tiến trình đang bận để tương tác;
}

private void btnNgungTienTrinhXuLy_Click(object sender, EventArgs e)
{
    //Ngừng tiến trình đang xử lý;
    backgroundWorker1.CancelAsync();
    txtKetQuaXuLyTienTrinh.Text = string.Empty;
    demQuaTrinhXuLyDangChay = 0;
}

Bây giờ bạn tiến hành Build dự án của mình để xem kết quả. Đối với việc xử lý các tiến trình khác các bạn làm tương tự, tùy vào mục đích yêu cầu mà xây dựng lưu trữ, sử dụng các tiến trình làm việc với nhau sao cho hợp lý.

Download Source Code mẫu

Share code mẫu sử dụng BackgroundWorker xây dựng ứng dụng chạy nền trong C#
Mã nguồn: C#
  • Code mẫu sử dụng BackgroundWorker để viết ứng dụng chạy nền trong window form C#.
  • Ví dụ sẽ mô phỏng chạy các tiến trình dạng Thread, tạm ngừng, chạy tiếp,...

XEM THÊM

Trả lời