c# 線程淺析(代理 、Invoke、Lock)

前言:原本想根據本身的經驗總結一下c#線程相關的知識點, 寫以前看了一些其餘人的博客,發現本身也就掌握了不到三分之一。。。。但願經過此次的博客將本身的知識點補充一下,寫出更直白的博客和初學者分享。html

這是我參考的博客地址:http://www.cnblogs.com/miniwiki/archive/2010/06/18/1760540.html  。編程

這個是他參考的英文原著地址:http://www.albahari.com/threading/c#

原博客介紹的能夠說深刻淺出,鞭辟入裏。不過我想寫出更適合小白的,直接拿去就能夠用到程序裏的博客。多線程

 

一. 什麼是線程(知道下面幾點有助於瞭解)this

1. 一個CPU同一時間只能作一件事,不過它處理信息太快了,甚至咱們使用它的時候,把它分紅了不少的時鐘週期(就是很短的時間間隔),再去把這些之間間隔分配個不一樣的應用,它也能很順暢的完成處理。就好像它能同時處理不少事同樣,咱們根據這一點,就能夠進行多線程,和多進程編程了。spa

2.進程是資源分配的基本單位。咱們建立一個程序,默認是一個進程的,這個進程中包含了一個線程(主線程)。如今咱們要在這個基礎上再去進行建立新的線程。(不少時候須要這樣)線程

3.進程中的線程,能夠共享進程中的資源。3d

4.線程是系統獨立調度和分派CPU的基本單位指運行中的程序的調度單位。代理

 

二.爲何要開啓新的線程調試

 有不少時候主線程處理數據消耗太多時間,致使鼠標不能用,程序看起來卡住了。這時候,咱們能夠把消耗時間的事放到一個單獨的線程裏,讓主線程輕鬆起來。

 

三. 多線程的使用

1.目標

在主線程中開啓一個線程,線程傳回數據在主窗體中的文本框中顯示。

 下面是全部的代碼,其中包括了代理 、Invoke、Lock,的使用。這個小的例子就能夠幫助你開始使用線程了。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace 線程淺析
{
     //建立SetValue的委託
    public delegate void SetValueDel(string str,object obj);

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Thread.CurrentThread.Name = "MainThread";
        }

        //開啓一個線程
        private void btnStart_Click(object sender, EventArgs e)
        {
            //將委託的方法和主窗體傳過去
            NEWThreadClass threadOneClass = new NEWThreadClass(SetValue, this);

            Thread TheThreadOne = new Thread(threadOneClass.threadOne);//不須要ThreadStart()也能夠

            TheThreadOne.Name = "TheThreadOne";//給線程命名,方便調試。這行代碼能夠省略。

            //讓線程變爲後臺線程(默認是前臺的),這樣主線程結束了,這個線程也會結束。要否則,任何前臺線程在運行都會保持程序存活。
            TheThreadOne.IsBackground = true;
            TheThreadOne.Start();
        }

        //給文本框賦值
        private void SetValue(string str, object obj)
        {
            //lock裏面的代碼同一個時刻,只能被一個線程使用。其它的後面排隊。這樣防止數據混亂。
            lock (obj)
            {
                this.txtReturnValue.Text = this.txtReturnValue.Text + str;
            }
        }
    }

    //建一個類,模擬實際使用狀況
    public class NEWThreadClass
    {
        //接收主窗體傳過來的委託方法。
        public SetValueDel setValueDel;

        //接收主窗體
        public Form form;

        //用於告訴主線程中鎖,是哪個線程調用的。
        static object locker = new object();

        public NEWThreadClass(SetValueDel del ,Form fom)
        {
            this.setValueDel = del; 
            this.form = fom;
        }
        //第一個線程,給主線程建立的控件傳值。
        public  void threadOne()
        {
            //這裏獲取線程的名字
            string threadName = Thread.CurrentThread.Name;
            try
            {
                while (true)
                {
                    //告訴主線程,我要更改你的控件了。
                    this.form.Invoke((EventHandler)(delegate
                    {
                        //若是在這裏使用Thread.CurrentThread.Name 獲取到的是主線程的名字。
                        setValueDel(threadName + " :Hello!", locker);//給文本框傳值,「本身的名字:Hello!」。
                    }));
                    Thread.Sleep(3 * 1000);//太累了 ,休息三秒。。。。
                }
            }
            catch (Exception ex)
            { }
        }
    }
}
相關文章
相關標籤/搜索