麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > C# > 正文

c# winform多線程的小例子

2020-01-24 03:28:40
字體:
來源:轉載
供稿:網友

在文本框中輸入一個數字,點擊開始累加按鈕,程序計算從1開始累計到該數字的結果。因為該累加過程比較耗時,如果直接在UI線程中進行,那么當前窗口將出現假死。為了有更好的用戶體驗,程序啟動一個新的線程來單獨執行該計算,然后每隔200毫秒讀取一次累加結果,并把結果顯示到文本框下方的label控件中。同時,程序支持取消操作,點擊取消累計按鈕,程序將取消累加操作,并把當前累加值顯示到label中。為了方便后面的描述,我把UI線程稱作主線程,把執行累加計算的線程稱作工作者線程。該過程有兩個關鍵點:

1:如何在工作者線程中訪問主線程創建的控件;

2:如何取消比較耗時的計算;

為了便于在工作者線程中調用累加過程,我把它寫成一個單獨方法,如下:

復制代碼 代碼如下:

/// <summary>
        /// 從1累加到指定的值,為了讓該方法支持取消操作所以需要CancellationToken參數
        /// </summary>
        /// <param name="countTo">累加到的指定值</param>
        /// <param name="ct">取消憑證</param>
        private void CountTo(int countTo, CancellationToken ct) {
            int sum = 0;
            for (; countTo > 0; countTo--) {
                if (ct.IsCancellationRequested) {
                    break;
                }
                sum += countTo;
                //Invoke方法用于獲得創建lbl_Status的線程所在的上下文
                this.Invoke(new Action(()=>lbl_Status.Text = sum.ToString()));               
                Thread.Sleep(200);
            }
        }

該方法就是用于累加數字,它有兩個需要注意的地方

1:方法需要傳遞一個CancellationToken參數,用于支持取消操作(《clr via c# 3版》中把這種方式稱作協作式取消,也就是說某一個操作必須支持取消,然后才能取消該操作);

2:為了允許工作者線程訪問主線程創建的lbl_Status控件,我在該線程中使用this.Invoke方法。該方法用于獲得主線程所創建控件的訪問權。它需要一個委托作為參數,在該委托中我們可以定義對lbl_Status的操作。例如在上例中我就是把當前的累加結果賦給lbl_Status的Text屬性。

然后我們看一下如何在一個共走著線程中執行計算耗時的操作,也就是“開始累加”按鈕的操作:

復制代碼 代碼如下:

private void btn_Count_Click(object sender, EventArgs e)
        {
            _cts = new CancellationTokenSource();
            ThreadPool.QueueUserWorkItem(state=>CountTo(int.Parse(txt_CountTo.Text),_cts.Token));
        }

我使用線程池線程來執行該操作,之所以使用線程池線程而不是自己的Threading對象,是因為線程池默認已經為我們創建好了一些線程,從而省去創建新線程造成的一些列資源消耗,同時,完成計算任務后該線程池線程自動回到池中等待下一個任務。我把_cts作為一個成員變量,聲明如下:

復制代碼 代碼如下:

private CancellationTokenSource _cts;

它需要引入using System.Threading;命名空間。

取消操作更加簡單,代碼如下:

復制代碼 代碼如下:

private void btn_Cancel_Click(object sender, EventArgs e)
        {
            if (_cts != null)
                _cts.Cancel();
        }

這樣我們就完成了在winform中使用多線程的例子,同時該例子支持取消操作。完整代碼如下:

復制代碼 代碼如下:

using System;
using System.Threading;
using System.Windows.Forms;

namespace WinformApp
{
    public partial class Form1 : Form
    {
        private CancellationTokenSource _cts;
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 從1累加到指定的值,為了讓該方法支持取消操作所以需要CancellationToken參數
        /// </summary>
        /// <param name="countTo">累加到的指定值</param>
        /// <param name="ct">取消憑證</param>
        private void CountTo(int countTo, CancellationToken ct) {
            int sum = 0;
            for (; countTo > 0; countTo--) {
                if (ct.IsCancellationRequested) {
                    break;
                }
                sum += countTo;
                //Invoke方法用于獲得創建lbl_Status的線程所在的上下文
                this.Invoke(new Action(()=>lbl_Status.Text = sum.ToString()));

                Thread.Sleep(200);
            }
        }

        private void btn_Count_Click(object sender, EventArgs e)
        {
            _cts = new CancellationTokenSource();
            ThreadPool.QueueUserWorkItem(state=>CountTo(int.Parse(txt_CountTo.Text),_cts.Token));
        }

        private void btn_Cancel_Click(object sender, EventArgs e)
        {
            if (_cts != null)
                _cts.Cancel();
        }

        private void btn_Pause_Click(object sender, EventArgs e)
        {

        }

    }
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产一级片91 | 欧美成人高清视频 | 欧洲a级片 | 日本视频在线免费观看 | 日本在线播放一区二区三区 | 鲁久久 | 亚洲精品在线观看免费 | 国产一级aa大片毛片 | 草碰人人| 羞羞视频免费观看入口 | 欧美成人精品h版在线观看 久久久久久三区 | 激情网站在线观看 | 欧美黑大粗硬毛片视频 | 欧美一级高潮 | 欧美一级棒 | 久久蜜桃精品一区二区三区综合网 | 中文在线免费观看 | 国产美女视频一区 | 中文字幕一区久久 | 久久久久久久一区二区 | 精品在线一区二区三区 | 色网免费观看 | 一级毛片大片 | 国产一级αv片免费观看 | 国产亚洲精品久久久闺蜜 | 91久久国产综合久久91猫猫 | 手机av免费电影 | 久久久一二三 | 国产91在线亚洲 | 高清一区二区在线观看 | 一区二区三区日本在线观看 | 欧美视屏一区二区 | 在线亚洲综合 | 91成人影库| 午夜精品网 | 久久久久久久免费精品 | 精品成人国产在线观看男人呻吟 | 久久99在线 | 99精品视频免费 | 亚洲自拍第二页 | 精品国产乱码久久久久久久 |