Hi guys, wish everyone a productive and energetic day. Today I will introduce about background workers in .NET.
Don’t let you wait long, let’s start with the article. In this article, I will talk about the definition, properties, methods, events and how to use background workers in .NET.
1. What is a background worker?
- BackgroundWorker is a class provided by the .NET Framework to perform long-running tasks or synchronous work on an independent thread, helping to avoid application block when performing tasks. heavy duty.
- BackgroundWorker is commonly used in Windows Forms or WPF applications to perform time-consuming tasks and update the UI continuously.
- Background workers are not available with .NET core. But .NET framework, .NET 5 and .NET 6 (long-term support) have support.
Note: but one note is that with .NET 5 and .NET 6, it is not recommended to use Background workers. It is recommended to use Task-based Asynchronous Programming (TAP) like tasks, async, await.. to perform long-running tasks.
2. Benefits of using background workers
- Avoid blocking UI: If you do heavy work in the main program (UI thread), it can block the application, making it impossible for users to interact with the application while these jobs are being done. BackgroundWorker helps to perform these jobs on an independent thread, avoiding application block and allowing users to continue interacting with the application.
- Update job progress: BackgroundWorker provides the ProgressChanged event, which allows you to update the progress of work on the UI continuously. This helps the user to know the status of the work and increases the user experience.
- Easy task management: BackgroundWorker provides methods for task management, allowing you to start or cancel tasks easily.
- Easy integration into Windows Forms or WPF applications: BackgroundWorker is designed for easy and flexible integration into Windows Forms or WPF applications.
3. Properties in the background worker
Here are some commonly used attributes and examples:
- WorkerReportsProgress: Get or Set the value that allows BackgroundWorker to support progress reporting. Progress reported events in BackgroundWorker are used to notify the progress of a background job to the UI thread. When the WorkerReportsProgress property is set to true, you can use the ReportProgress method to report the progress of background work.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">backgroundWorker1_DoWork</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">DoWorkEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">BackgroundWorker</span> worker <span class="token operator">=</span> sender <span class="token keyword">as</span> <span class="token class-name">BackgroundWorker</span> <span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">int</span></span> total <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token keyword">int</span> <span class="token punctuation">)</span> e <span class="token punctuation">.</span> Argument <span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">int</span></span> i <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">;</span> i <span class="token operator"><=</span> total <span class="token punctuation">;</span> i <span class="token operator">++</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> worker <span class="token punctuation">.</span> CancellationPending <span class="token punctuation">)</span> <span class="token punctuation">{</span> e <span class="token punctuation">.</span> Cancel <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">;</span> <span class="token keyword">break</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Báo cáo tiến trình cho người dùng</span> <span class="token class-name"><span class="token keyword">int</span></span> progressPercentage <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token keyword">int</span> <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token keyword">float</span> <span class="token punctuation">)</span> i <span class="token operator">/</span> <span class="token punctuation">(</span> <span class="token keyword">float</span> <span class="token punctuation">)</span> total <span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> worker <span class="token punctuation">.</span> <span class="token function">ReportProgress</span> <span class="token punctuation">(</span> progressPercentage <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Thực hiện công việc nền</span> Thread <span class="token punctuation">.</span> <span class="token function">Sleep</span> <span class="token punctuation">(</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">backgroundWorker1_ProgressChanged</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">ProgressChangedEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Cập nhật tiến trình của công việc nền cho người dùng</span> progressBar1 <span class="token punctuation">.</span> Value <span class="token operator">=</span> e <span class="token punctuation">.</span> ProgressPercentage <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">button1_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Khởi động BackgroundWorker để thực hiện công việc nền</span> backgroundWorker1 <span class="token punctuation">.</span> WorkerReportsProgress <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">;</span> backgroundWorker1 <span class="token punctuation">.</span> <span class="token function">RunWorkerAsync</span> <span class="token punctuation">(</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
- WorkerSupportsCancellation: The WorkerSupportsCancellation property in the BackgroundWorker is used to allow the user to cancel a running background job. When this property is set to true, you can use the CancelAsync method to cancel a background job.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">backgroundWorker1_DoWork</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">DoWorkEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">BackgroundWorker</span> worker <span class="token operator">=</span> sender <span class="token keyword">as</span> <span class="token class-name">BackgroundWorker</span> <span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">int</span></span> total <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token keyword">int</span> <span class="token punctuation">)</span> e <span class="token punctuation">.</span> Argument <span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">int</span></span> i <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">;</span> i <span class="token operator"><=</span> total <span class="token punctuation">;</span> i <span class="token operator">++</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> worker <span class="token punctuation">.</span> CancellationPending <span class="token punctuation">)</span> <span class="token punctuation">{</span> e <span class="token punctuation">.</span> Cancel <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">;</span> <span class="token keyword">break</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Thực hiện công việc nền</span> Thread <span class="token punctuation">.</span> <span class="token function">Sleep</span> <span class="token punctuation">(</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">button1_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Khởi động BackgroundWorker để thực hiện công việc nền</span> backgroundWorker1 <span class="token punctuation">.</span> WorkerSupportsCancellation <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">;</span> backgroundWorker1 <span class="token punctuation">.</span> <span class="token function">RunWorkerAsync</span> <span class="token punctuation">(</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">button2_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Hủy thực hiện công việc nền</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> backgroundWorker1 <span class="token punctuation">.</span> IsBusy <span class="token punctuation">)</span> <span class="token punctuation">{</span> backgroundWorker1 <span class="token punctuation">.</span> <span class="token function">CancelAsync</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">backgroundWorker1_RunWorkerCompleted</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">RunWorkerCompletedEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Cancelled <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Công việc nền đã bị hủy bởi người dùng</span> MessageBox <span class="token punctuation">.</span> <span class="token function">Show</span> <span class="token punctuation">(</span> "Công vi |
- CancellationPending: Gets the value to check if the user has requested to cancel the execution of a background job. Returns boolean.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">backgroundWorker1_DoWork</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">DoWorkEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">BackgroundWorker</span> worker <span class="token operator">=</span> sender <span class="token keyword">as</span> <span class="token class-name">BackgroundWorker</span> <span class="token punctuation">;</span> <span class="token class-name"><span class="token keyword">int</span></span> total <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token keyword">int</span> <span class="token punctuation">)</span> e <span class="token punctuation">.</span> Argument <span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">int</span></span> i <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">;</span> i <span class="token operator"><=</span> total <span class="token punctuation">;</span> i <span class="token operator">++</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> worker <span class="token punctuation">.</span> CancellationPending <span class="token punctuation">)</span> <span class="token punctuation">{</span> e <span class="token punctuation">.</span> Cancel <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">;</span> <span class="token keyword">break</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Thực hiện công việc nền</span> Thread <span class="token punctuation">.</span> <span class="token function">Sleep</span> <span class="token punctuation">(</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> worker <span class="token punctuation">.</span> <span class="token function">ReportProgress</span> <span class="token punctuation">(</span> i <span class="token operator">*</span> <span class="token number">100</span> <span class="token operator">/</span> total <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">button1_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Khởi động BackgroundWorker để thực hiện công việc nền</span> backgroundWorker1 <span class="token punctuation">.</span> <span class="token function">RunWorkerAsync</span> <span class="token punctuation">(</span> <span class="token number">100</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">button2_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Hủy thực hiện công việc nền</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> backgroundWorker1 <span class="token punctuation">.</span> IsBusy <span class="token punctuation">)</span> <span class="token punctuation">{</span> backgroundWorker1 <span class="token punctuation">.</span> <span class="token function">CancelAsync</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">backgroundWorker1_ProgressChanged</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">ProgressChangedEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Cập nhật trạng thái của công việc nền</span> progressBar1 <span class="token punctuation">.</span> Value <span class="token operator">=</span> e <span class="token punctuation">.</span> ProgressPercentage <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">backgroundWorker1_RunWorkerCompleted</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">RunWorkerCompletedEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Cancelled <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Công việc nền đã bị hủy bởi người dùng</span> MessageBox <span class="token punctuation">.</span> <span class="token function">Show</span> <span class="token punctuation">(</span> <span class="token string">"Công việc nền đã bị hủy bởi người dùng."</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Error <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Xảy ra lỗi trong quá trình thực hiện công việc nền</span> MessageBox <span class="token punctuation">.</span> <span class="token function">Show</span> <span class="token punctuation">(</span> <span class="token string">"Xảy ra lỗi trong quá trình thực hiện công việc nền: "</span> <span class="token operator">+</span> e <span class="token punctuation">.</span> Error <span class="token punctuation">.</span> Message <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Công việc nền đã thực hiện xong</span> MessageBox <span class="token punctuation">.</span> <span class="token function">Show</span> <span class="token punctuation">(</span> <span class="token string">"Công việc nền đã thực hiện xong."</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
- IsBusy: Gets the value indicating whether the BackgroundWorker is running a background activity.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <span class="token keyword">private</span> <span class="token class-name">BackgroundWorker</span> _worker <span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">buttonStart_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> _worker <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">BackgroundWorker</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> _worker <span class="token punctuation">.</span> DoWork <span class="token operator">+=</span> Worker_DoWork <span class="token punctuation">;</span> _worker <span class="token punctuation">.</span> RunWorkerCompleted <span class="token operator">+=</span> Worker_RunWorkerCompleted <span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span> _worker <span class="token punctuation">.</span> IsBusy <span class="token punctuation">)</span> <span class="token punctuation">{</span> _worker <span class="token punctuation">.</span> <span class="token function">RunWorkerAsync</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker started."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker is already running."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Worker_DoWork</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">DoWorkEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Perform a long-running operation here...</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Worker_RunWorkerCompleted</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">RunWorkerCompletedEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker completed."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
- DoWorkEventArgs: Gets the argument passed to the DoWork event handler.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <span class="token keyword">private</span> <span class="token class-name">BackgroundWorker</span> _worker <span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">buttonStart_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> _worker <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">BackgroundWorker</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> _worker <span class="token punctuation">.</span> DoWork <span class="token operator">+=</span> Worker_DoWork <span class="token punctuation">;</span> _worker <span class="token punctuation">.</span> RunWorkerCompleted <span class="token operator">+=</span> Worker_RunWorkerCompleted <span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span> _worker <span class="token punctuation">.</span> IsBusy <span class="token punctuation">)</span> <span class="token punctuation">{</span> _worker <span class="token punctuation">.</span> <span class="token function">RunWorkerAsync</span> <span class="token punctuation">(</span> textBoxInput <span class="token punctuation">.</span> Text <span class="token punctuation">)</span> <span class="token punctuation">;</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker started."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker is already running."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Worker_DoWork</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">DoWorkEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">string</span></span> input <span class="token operator">=</span> e <span class="token punctuation">.</span> Argument <span class="token keyword">as</span> <span class="token class-name"><span class="token keyword">string</span></span> <span class="token punctuation">;</span> <span class="token comment">// Perform some operation with the input...</span> e <span class="token punctuation">.</span> Result <span class="token operator">=</span> <span class="token string">"Output"</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Worker_RunWorkerCompleted</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">RunWorkerCompletedEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Error <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker encountered an error: "</span> <span class="token operator">+</span> e <span class="token punctuation">.</span> Error <span class="token punctuation">.</span> Message <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Cancelled <span class="token punctuation">)</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker was cancelled."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">string</span></span> output <span class="token operator">=</span> e <span class="token punctuation">.</span> Result <span class="token keyword">as</span> <span class="token class-name"><span class="token keyword">string</span></span> <span class="token punctuation">;</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker completed with output: "</span> <span class="token operator">+</span> output <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
- Error: Get error if any error occurs during execution of background activity.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <span class="token keyword">private</span> <span class="token class-name">BackgroundWorker</span> _worker <span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">buttonStart_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> _worker <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">BackgroundWorker</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> _worker <span class="token punctuation">.</span> DoWork <span class="token operator">+=</span> Worker_DoWork <span class="token punctuation">;</span> _worker <span class="token punctuation">.</span> RunWorkerCompleted <span class="token operator">+=</span> Worker_RunWorkerCompleted <span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span> _worker <span class="token punctuation">.</span> IsBusy <span class="token punctuation">)</span> <span class="token punctuation">{</span> _worker <span class="token punctuation">.</span> <span class="token function">RunWorkerAsync</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker started."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker is already running."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Worker_DoWork</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">DoWorkEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment">// Perform some operation that might throw an exception...</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span> <span class="token class-name">Exception</span> ex <span class="token punctuation">)</span> <span class="token punctuation">{</span> e <span class="token punctuation">.</span> Result <span class="token operator">=</span> <span class="token keyword">null</span> <span class="token punctuation">;</span> e <span class="token punctuation">.</span> Cancel <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">;</span> e <span class="token punctuation">.</span> Error <span class="token operator">=</span> ex <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Worker_RunWorkerCompleted</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">RunWorkerCompletedEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Error <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker encountered an error: "</span> <span class="token operator">+</span> e <span class="token punctuation">.</span> Error <span class="token punctuation">.</span> Message <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Cancelled <span class="token punctuation">)</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker was cancelled."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Do something with the result...</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
- Result: Get the result of the background activity.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <span class="token keyword">private</span> <span class="token class-name">BackgroundWorker</span> _worker <span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">buttonStart_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> _worker <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">BackgroundWorker</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> _worker <span class="token punctuation">.</span> DoWork <span class="token operator">+=</span> Worker_DoWork <span class="token punctuation">;</span> _worker <span class="token punctuation">.</span> RunWorkerCompleted <span class="token operator">+=</span> Worker_RunWorkerCompleted <span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span> _worker <span class="token punctuation">.</span> IsBusy <span class="token punctuation">)</span> <span class="token punctuation">{</span> _worker <span class="token punctuation">.</span> <span class="token function">RunWorkerAsync</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker started."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker is already running."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Worker_DoWork</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">DoWorkEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Perform some long-running operation...</span> e <span class="token punctuation">.</span> Result <span class="token operator">=</span> <span class="token string">"Result of the operation"</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Worker_RunWorkerCompleted</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">RunWorkerCompletedEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Error <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker encountered an error: "</span> <span class="token operator">+</span> e <span class="token punctuation">.</span> Error <span class="token punctuation">.</span> Message <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Cancelled <span class="token punctuation">)</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker was cancelled."</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> labelStatus <span class="token punctuation">.</span> Text <span class="token operator">=</span> <span class="token string">"Worker completed with result: "</span> <span class="token operator">+</span> e <span class="token punctuation">.</span> Result <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
4. Methods in the background worker
- CancelAsync() : Request to cancel the job in progress by setting the CancellationPending value to true.
- ReportProgress(int percentProgress, object userState) : Report the progress of the work in progress and pass additional data (if any) via the userState argument.
- RunWorkerAsync(object argument) : Send request to start background job execution and pass parameters (if any).
- Dispose() : Releases resources used by BackgroundWorker.
In addition, BackgroundWorker also provides events to allow the application to respond when a job is running:
- DoWork : The event that occurs when the job starts executing.
- ProgressChanged : Event occurs when the progress of the job is reported.
- RunWorkerCompleted : Event occurs when the job is completed or cancelled.
5. Some use cases use background workers
- Downloading large data from the Internet: When the application needs to download large data from the internet, doing it in the UI thread itself will make the application freeze and become unresponsive. In this case, the Background Worker can be used to load the data in the background, and update the progress of the data loading via the ProgressChanged event.
- Handling Big Data: When the application needs to process big data, for example image format conversion, doing it in the UI thread itself will cause the application to freeze and become unresponsive. In this case, the Background Worker can be used to process the data in the background, and update the progress of the processing via the ProgressChanged event.
- Sending Emails: When the app needs to send emails, doing so in the UI thread itself causes the app to freeze and become unresponsive. In this case, it is possible to use the Background Worker to send emails in the background, and update the email delivery progress via the ProgressChanged event.
- Read data from file: When the application needs to read data from a large file, doing so in the UI thread itself will cause the application to freeze and become unresponsive. In this case, the Background Worker can be used to read the data in the background, and update the progress of the reading via the ProgressChanged event.
- Complex computations: When the application needs to perform complex calculations, such as calculating curves in graphics, doing so in the UI thread itself will make the application freeze and unresponsive. In this case, it is possible to use the Background Worker to calculate in the background, and update the progress of the calculation via the ProgressChanged event.
Example of using background workers when downloading data from the internet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">btnDownload_Click</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">EventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token operator">!</span> bgwDownload <span class="token punctuation">.</span> IsBusy <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Lấy URL từ TextBox</span> <span class="token class-name"><span class="token keyword">string</span></span> url <span class="token operator">=</span> txtURL <span class="token punctuation">.</span> Text <span class="token punctuation">;</span> <span class="token comment">// Bắt đầu tiến trình</span> bgwDownload <span class="token punctuation">.</span> <span class="token function">RunWorkerAsync</span> <span class="token punctuation">(</span> url <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">bgwDownload_DoWork</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">DoWorkEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Lấy URL từ tham số của tiến trình</span> <span class="token class-name"><span class="token keyword">string</span></span> url <span class="token operator">=</span> e <span class="token punctuation">.</span> Argument <span class="token keyword">as</span> <span class="token class-name"><span class="token keyword">string</span></span> <span class="token punctuation">;</span> <span class="token comment">// Sử dụng HttpClient để tải dữ liệu từ URL</span> <span class="token keyword">using</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">var</span></span> client <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HttpClient</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">var</span></span> response <span class="token operator">=</span> client <span class="token punctuation">.</span> <span class="token function">GetAsync</span> <span class="token punctuation">(</span> url <span class="token punctuation">)</span> <span class="token punctuation">.</span> Result <span class="token punctuation">;</span> <span class="token comment">// Nếu yêu cầu thành công, đọc dữ liệu từ phản hồi và trả về cho tiến trình</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> response <span class="token punctuation">.</span> IsSuccessStatusCode <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name"><span class="token keyword">var</span></span> content <span class="token operator">=</span> response <span class="token punctuation">.</span> Content <span class="token punctuation">.</span> <span class="token function">ReadAsStringAsync</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> Result <span class="token punctuation">;</span> e <span class="token punctuation">.</span> Result <span class="token operator">=</span> content <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Nếu yêu cầu không thành công, báo lỗi cho tiến trình</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Exception</span> <span class="token punctuation">(</span> <span class="token string">"Lỗi tải dữ liệu từ mạng."</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">bgwDownload_RunWorkerCompleted</span> <span class="token punctuation">(</span> <span class="token class-name"><span class="token keyword">object</span></span> sender <span class="token punctuation">,</span> <span class="token class-name">RunWorkerCompletedEventArgs</span> e <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Nếu tiến trình bị hủy, không cập nhật UI</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Cancelled <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Nếu tiến trình không có lỗi, hiển thị dữ liệu trong TextBox</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Error <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> txtData <span class="token punctuation">.</span> Text <span class="token operator">=</span> e <span class="token punctuation">.</span> Result <span class="token keyword">as</span> <span class="token class-name"><span class="token keyword">string</span></span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Nếu có lỗi, hiển thị thông báo cho người dùng</span> MessageBox <span class="token punctuation">.</span> <span class="token function">Show</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> Error <span class="token punctuation">.</span> Message <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |