欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c# winform多線程的小例子

 更新時(shí)間:2013年04月14日 10:37:52   作者:  
c# winform多線程的小例子,需要的朋友可以參考一下

在文本框中輸入一個(gè)數(shù)字,點(diǎn)擊開始累加按鈕,程序計(jì)算從1開始累計(jì)到該數(shù)字的結(jié)果。因?yàn)樵摾奂舆^程比較耗時(shí),如果直接在UI線程中進(jìn)行,那么當(dāng)前窗口將出現(xiàn)假死。為了有更好的用戶體驗(yàn),程序啟動(dòng)一個(gè)新的線程來單獨(dú)執(zhí)行該計(jì)算,然后每隔200毫秒讀取一次累加結(jié)果,并把結(jié)果顯示到文本框下方的label控件中。同時(shí),程序支持取消操作,點(diǎn)擊取消累計(jì)按鈕,程序?qū)⑷∠奂硬僮?,并把?dāng)前累加值顯示到label中。為了方便后面的描述,我把UI線程稱作主線程,把執(zhí)行累加計(jì)算的線程稱作工作者線程。該過程有兩個(gè)關(guān)鍵點(diǎn):

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

2:如何取消比較耗時(shí)的計(jì)算;

為了便于在工作者線程中調(diào)用累加過程,我把它寫成一個(gè)單獨(dú)方法,如下:

復(fù)制代碼 代碼如下:

/// <summary>
        /// 從1累加到指定的值,為了讓該方法支持取消操作所以需要CancellationToken參數(shù)
        /// </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方法用于獲得創(chuàng)建lbl_Status的線程所在的上下文
                this.Invoke(new Action(()=>lbl_Status.Text = sum.ToString()));               
                Thread.Sleep(200);
            }
        }

該方法就是用于累加數(shù)字,它有兩個(gè)需要注意的地方

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

2:為了允許工作者線程訪問主線程創(chuàng)建的lbl_Status控件,我在該線程中使用this.Invoke方法。該方法用于獲得主線程所創(chuàng)建控件的訪問權(quán)。它需要一個(gè)委托作為參數(shù),在該委托中我們可以定義對(duì)lbl_Status的操作。例如在上例中我就是把當(dāng)前的累加結(jié)果賦給lbl_Status的Text屬性。

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

復(fù)制代碼 代碼如下:

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

我使用線程池線程來執(zhí)行該操作,之所以使用線程池線程而不是自己的Threading對(duì)象,是因?yàn)榫€程池默認(rèn)已經(jīng)為我們創(chuàng)建好了一些線程,從而省去創(chuàng)建新線程造成的一些列資源消耗,同時(shí),完成計(jì)算任務(wù)后該線程池線程自動(dòng)回到池中等待下一個(gè)任務(wù)。我把_cts作為一個(gè)成員變量,聲明如下:

復(fù)制代碼 代碼如下:

private CancellationTokenSource _cts;

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

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

復(fù)制代碼 代碼如下:

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

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

復(fù)制代碼 代碼如下:

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參數(shù)
        /// </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方法用于獲得創(chuàng)建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)
        {

        }

    }
}

相關(guān)文章

  • c# Parallel類的使用

    c# Parallel類的使用

    這篇文章主要介紹了c# Parallel類的使用,幫助大家實(shí)現(xiàn)數(shù)據(jù)與任務(wù)的并行,感興趣的朋友可以了解下
    2020-11-11
  • UGUI實(shí)現(xiàn)圖片拖拽功能

    UGUI實(shí)現(xiàn)圖片拖拽功能

    這篇文章主要為大家詳細(xì)介紹了UGUI實(shí)現(xiàn)圖片拖拽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • C#私有構(gòu)造函數(shù)使用示例

    C#私有構(gòu)造函數(shù)使用示例

    本文主要介紹了C#私有構(gòu)造函數(shù)使用方法,私有構(gòu)造函數(shù)是一種特殊的實(shí)例構(gòu)造函數(shù)。它通常用在只包含靜態(tài)成員的類中。如果類具有一個(gè)或多個(gè)私有構(gòu)造函數(shù)而沒有公共構(gòu)造函數(shù),則其他類(除嵌套類外)無法創(chuàng)建該類的實(shí)例
    2014-01-01
  • 關(guān)于C#中使用Oracle存儲(chǔ)過程返回結(jié)果集的問題

    關(guān)于C#中使用Oracle存儲(chǔ)過程返回結(jié)果集的問題

    Oracle中可以使用游標(biāo)(Cursor)對(duì)數(shù)據(jù)集進(jìn)行操作,但在存儲(chǔ)過程輸出參數(shù)中直接使用Cursor錯(cuò)誤,下面小編給大家?guī)砹薈#中使用Oracle存儲(chǔ)過程返回結(jié)果集的問題,感興趣的朋友一起看看吧
    2021-10-10
  • C#利用Random得隨機(jī)數(shù)求均值、方差、正態(tài)分布的方法

    C#利用Random得隨機(jī)數(shù)求均值、方差、正態(tài)分布的方法

    這篇文章主要介紹了C#利用Random得隨機(jī)數(shù)求均值、方差、正態(tài)分布的方法,涉及C#數(shù)學(xué)運(yùn)算及概率統(tǒng)計(jì)的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • WinForm中快捷鍵與組合按鍵的設(shè)置方法

    WinForm中快捷鍵與組合按鍵的設(shè)置方法

    WinForm中快捷鍵與組合按鍵的設(shè)置,第一種方法。。代碼復(fù)雜,操作簡單的快捷鍵,另外一種簡單快捷鍵的方法,大家可以參考下
    2013-02-02
  • C#多線程死鎖介紹與案例代碼

    C#多線程死鎖介紹與案例代碼

    這篇文章介紹了C#多線程的死鎖,并使用案例代碼實(shí)現(xiàn)解決方案,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • C#實(shí)現(xiàn)子窗體與父窗體通信方法實(shí)例總結(jié)

    C#實(shí)現(xiàn)子窗體與父窗體通信方法實(shí)例總結(jié)

    這篇文章主要介紹了C#實(shí)現(xiàn)子窗體與父窗體通信方法,實(shí)例總結(jié)了常用的四種窗體通信方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-09-09
  • c# datetime 格式化大全

    c# datetime 格式化大全

    這篇文章主要介紹了c# datetime 格式化大全,有需要的朋友可以參考一下
    2014-01-01
  • C#實(shí)現(xiàn)批量壓縮和解壓縮的示例代碼

    C#實(shí)現(xiàn)批量壓縮和解壓縮的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)批量壓縮和解壓縮的功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-12-12

最新評(píng)論