程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> c# 線程淺析(代理 、Invoke、Lock),

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

編輯:C#入門知識

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


前言:本來想根據自己的經驗總結一下c#線程相關的知識點, 寫之前看了一些其他人的博客,發現自己也就掌握了不到三分之一。。。。希望通過這次的博客將自己的知識點補充一下,寫出更直白的博客和初學者分享。

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

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

原博客介紹的可以說深入淺出,鞭辟入裡。不過我想寫出更適合小白的,直接拿去就可以用到程序裡的博客。

 

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

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

2.進程是資源分配的基本單位。我們創建一個程序,默認是一個進程的,這個進程中包含了一個線程(主線程)。現在我們要在這個基礎上再去進行創建新的線程。(很多時候需要這樣)

3.進程中的線程,可以共享進程中的資源。

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)
            { }
        }
    }
}

 

 

 

    

      

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved