1. 程式人生 > >多執行緒:C#.NET中使用BackgroundWorker在模態對話方塊中顯示進度條

多執行緒:C#.NET中使用BackgroundWorker在模態對話方塊中顯示進度條

我們使用C#.NET編寫WinForm程式時,有時候為了實現在模態對話方塊中實時顯示後臺操作的進度,這個時候需要藉助於多執行緒操作在子窗體中顯示進度條狀態,在父窗體中進行後臺操作。你可以在Thread類中自己建立兩個執行緒以完成這個操作,不過C#.NET提供了BackgroundWorker物件可以幫助我們非常方便地來實現這個過程。有關Backgroundworker物件的時候我在“C#遍歷檔案讀取Word內容以及實用BackgroundWoker物件打造平滑進度條”一文中有過介紹,大家可以去看看。

  這裡是一個示例,其中展示瞭如何使用Backgroundworker物件在模態對話方塊中顯示後臺操作的實時進度條。

  首先是主窗體程式碼:

複製程式碼  1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 using System.Threading;
10 11 namespace ModalProgressDialog
12 {
13 publicpartialclass Form1 : Form
14     {
15 protected BackgroundWorker worker =new BackgroundWorker();
16 protected Form2 frm =new Form2();
17
 18 public Form1()
19         {
20             worker.DoWork +=new DoWorkEventHandler(worker_DoWork);
21             worker.ProgressChanged +=new ProgressChangedEventHandler(worker_ProgressChanged);
22             worker.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
23
 24             InitializeComponent();
25         }
26 27 privatevoid button1_Click(object sender, EventArgs e)
28         {
29             worker.WorkerReportsProgress =true;            
30             worker.RunWorkerAsync();
31             frm.ShowDialog();
32         }
33 34 void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
35         {
36             frm.Close();
37             MessageBox.Show("Done");
38         }
39 40 void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
41         {
42             frm.ProgressValue = e.ProgressPercentage;
43         }
44 45 void worker_DoWork(object sender, DoWorkEventArgs e)
46         {
47             CountTheTime();
48         }
49 50 privatevoid CountTheTime()
51         {
52 int initialValue =100
53 for (int count =0; count < initialValue; count = count +2
54             { 
55                 Thread.Sleep(1000);
56                 worker.ReportProgress(count); 
57             }
58         }
59     }
60 } 複製程式碼

  主窗體中只有一個按鈕,當被點選時,會由BackgroundWorker物件以非同步的方式去執行一個假象的後臺操作CountTheTime方法。CountTheTime方法從0到100以步長為2每隔1秒更新一下進度條狀態,因此這個假象的後臺操作大約會持續50秒左右的時間。當程式執行時,進度條指示視窗以模態對話方塊的形式被彈出,然後實時顯示後臺操作的進度。

  BackgroundWorker物件有三個主要的事件:

  DoWork - 當BackgroundWorker物件的多執行緒操作被執行時觸發。

  RunWokerCompleted - 當BackgroundWoker物件的多執行緒操作完成時觸發。

  ProgressChanged - 當BackgroundWorker物件的多執行緒操作狀態改變時觸發。

  另外還有一個非常重要的屬性WorkerReportsProgress - 如果想讓BackgroundWorker物件以非同步的方式報告執行緒實時進度,必須將該屬性的值設為true。

  BackgroundWorker物件的ReportProgress方法用於向主執行緒返回後臺執行緒執行的實時進度。

  下面是子窗體的程式碼:

複製程式碼  1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Data;
 5 using System.Drawing;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 10 namespace ModalProgressDialog
11 {
12 publicpartialclass Form2 : Form
13     {
14 publicint ProgressValue 
15         {
16 get { returnthis.progressBar1.Value; }
17 set { progressBar1.Value = value; }
18         }
19 20 public Form2()
21         {
22             InitializeComponent();
23         }
24     }
25 } 複製程式碼

  子窗體中放置了一個ProgressBar控制元件,對外可以通過ProgressValue屬性來獲取和修改進度條的當前值。同時,我們可以將子窗體的FormBorderStyle屬性設為FixedDialog以使其看起來更像對話方塊,然後將MaximizeBoxMinimizeBox都設為false,將ControlBox屬性設為false以隱藏窗體關閉按鈕。在父窗體中,我們通過BackgroundWorker物件的RunWorkerAsync方法觸發DoWork事件,此時CountTheTime()方法被執行。在CountTheTime()方法中,通過ReportProgress()方法從後臺程序(父窗體)傳遞進度指示到主UI執行緒(子窗體)中,這樣同時會觸發ProgressChanged事件,然後我們在該事件中更新子窗體的進度條狀態。下面是程式執行時的截圖。

   注意,使用BackgroundWorker時不能在工作執行緒中訪問UI執行緒部分,即你不能在BackgroundWorker的事件和方法中操作UI,否則會拋跨執行緒操作無效的異常。常用的方法是在主窗體的建構函式中新增CheckForIllegalCrossThreadCalls = false;語句。或者使用Thread類建立一個單獨的執行緒,然後使用Invoke方法。可以參考下面這些內容:

相關推薦

執行C#.NET使用BackgroundWorker對話方塊顯示進度

我們使用C#.NET編寫WinForm程式時,有時候為了實現在模態對話方塊中實時顯示後臺操作的進度,這個時候需要藉助於多執行緒操作在子窗體中顯示進度條狀態,在父窗體中進行後臺操作。你可以在Thread類中自己建立兩個執行緒以完成這個操作,不過C#.NET提供了Backgro

微信小程式踩坑(1)wx.showModal對話方塊content換行

問題:wx.showModal 對話方塊內容不能換行? 如上圖所示,模態對話方塊中content是沒有換行的,但是我們需求中有需要換行提醒的業務,那怎麼辦呢?官方API中並沒有告訴我們怎麼做! 解決方案:使用“\r\n”換行 原始碼 wx.showModal({

MFC對話方塊和非對話方塊

MFC筆記之模態對話方塊和非模態對話方塊 迫於科研的進度壓力,我還是選擇了MFC最為工具去開發裝置除錯軟體,最初想用Qt來創新一下,然而串列埠的通訊一直沒有成功,而且周圍沒有人用Qt使得我在遇到問題無法

Bootstrap3 對話方塊無法顯示的問題

今天幫同事調了一個程式碼,他們的專案最近在用Bootstrap做開發,突然間,他遇到了一個奇怪的問題,如果一個頁面中,有多個Modal對話方塊的話,排列在第一個的對話方塊,能夠正確顯示,第二個,只能導致頁面出現MASK層,卻不能顯示Dialog. 如果調整順序,仍然是第一個

c++11執行std::future , std::promise和執行的返回值

std::future物件可以和asych,std::packaged_task,std::promise一起使用。這篇文章集中討論std::future和std::promise。 我們經常會遇到需要得到執行緒返回結果的情況,現在的問題是我們如何實現。 舉個例子: 假設

【本人禿頂程式設計師】執行為什麼在while迴圈加入System.out.println,執行可以停止

在論壇看到這樣一個程式碼: public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedE

執行為什麼在while迴圈加入System.out.println,執行可以停止

在論壇看到這樣一個程式碼: public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedE

linux執行程式設計(C)訊號量實現的執行安全佇列

用訊號量實現的執行緒安全佇列。 簡單有用的示例程式, 比起互斥量的實現在多執行緒時效率更好。 cir_queue.h /* * \File * cir_queue.h * \Brief * circular queue */#ifndef __CIR_QUEUE_H_

執行J.U.C

java.util.concurrent(J.U.C)大大提高了併發效能。 AQS 被認為是 J.U.C 的核心。 什麼是AQS?  AQS是AbstractQueuedSynchronizer的簡稱。AQS提供了一種實現阻塞鎖和一系列依賴FIFO等待佇列的同步器的框架。

java執行併發包ReentrantReadWriteLock讀寫鎖的鎖降級模板

寫鎖降級為讀鎖,但讀鎖不可升級或降級為寫鎖。 鎖降級是為了讓當前執行緒感知到資料的變化。 1 //讀寫鎖 2 private ReentrantReadWriteLock lock=new ReentrantReadWriteLock(); 3 //讀鎖 4

java執行併發包ReentrantReadWriteLock讀寫鎖的鎖降級模板 寫鎖降級為讀鎖

寫鎖降級為讀鎖,但讀鎖不可升級或降級為寫鎖。 鎖降級是為了讓當前執行緒感知到資料的變化。 1 //讀寫鎖 2 private ReentrantReadWriteLock lock=new ReentrantReadWriteLock(); 3 /

PYTHON——執行同步鎖Lock

一、先用一個例子說明沒有用鎖的時候,達到的效果錯誤: 1、例項(沒有鎖的情況): import time import threading # 沒有用鎖的 # 時候,出現多個執行緒拿到相同資源的現象。 # 如下例中,共享資源變數num=100,我們開100個執行緒,每個執行緒將資源變數num減1,按

PYTHON——執行訊號量(Semaphore)

  訊號量也是一把鎖,用來控制執行緒併發數的。   BoundedSemaphore或Semaphore管理一個內建的計數 器,每當呼叫acquire()時-1,呼叫release()時+1。       計數器不能小於0,當計數器為 0時,acquire()將阻塞執行緒至同

PYTHON——執行條件變數(Condition)

  條件變數(Condition)也是一把鎖,除了同步鎖的作用外,還具有線上程間通訊的功能。   有一類執行緒需要滿足條件之後才能夠繼續執行,Python提供了threading.Condition 物件用於條件變數執行緒的支援,它除了能提供RLock()或Lock()的方法外,還提供了 wait()、no

PYTHON——執行佇列Queue資料結構

1、佇列模組簡介   佇列是一種資料結構,用於存放資料,類似列表。它是先進先出模式(FIFO模式),類似管道一般; 單執行緒不需要用到佇列Queue,它主要用在多執行緒之間的,Queue稱為多執行緒利器。 列表在多執行緒共享資源的話,與queue佇列比較,主要表現為列表在多執行緒中,資料不安全。多個執行

執行基礎內容

一、iOS中的常見多執行緒方案 iOS 中 常見的多執行緒 方案 pthread 和 NSThread 是 程式設計師自己建立 執行緒,自己管理什麼時候開啟,什麼時候結束。 GCD 和 NSOperation 則不用程式設計師自己管理,是系統管理。

執行問題C++

關於多執行緒,一直都是一知半解,今天又看了些相關知識,總結下: 1.過去寫的微控制器裸跑的程式,其實也屬於多執行緒的,用智慧電錶中的韌體做個比方。 void main(void){ initilize_para();   //基礎引數的初始化 ..... while

執行Operation和OperationQueue

多執行緒:實現方式Operation和OperationQueue Operation 生命週期 //都有共同特點,只讀屬性。 //是否準備 open var isReady: Bool { get } //是否執行 open var isExecuting: Boo

java執行5.1 鎖-基礎

什麼是鎖 提到多執行緒,立馬就有人說加鎖,什麼是鎖,為什麼加鎖? 鎖:從字面意義,什麼東西加了鎖,那麼就只有有鑰匙的人才能使用,多執行緒中的鎖,也是這個意思。 為什麼加鎖:當單執行緒的時候,無論訪問什麼資源,都不需要考慮鎖的問題,但是當多個執行緒訪問同一個資源,就會發生很多千奇百怪的

java執行3 執行狀態

執行緒從建立到結束執行,經過多個狀態,每個狀態對應著不同的操作,具體如下: 1 建立(new),2 可以執行(runnable)、3 執行(running)、4 等待(waiting)、5 阻塞(blocked)、6 結束(dead) 建立執行緒 當通過new Thre