程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#編程總結(四)多線程應用

C#編程總結(四)多線程應用

編輯:關於C#

多線程應用很廣泛,簡單總結了一下:

1)不阻斷主線程,實現即時響應,由後台線程完成特定操作

2)多個線程,完成同類任務,提高並發性能

3)一個任務有多個獨立的步驟,多個線程並發執行各子任務,提高任務處理效率

下面我們通過幾個小例子做簡單介紹。

1、進度條

分析:頁面動態刷新,主頁面正常可操作。我們通過後台線程來實現進度條。

首先,創建Winform頁面,然後拖入進度條控件,將頁面的代碼改為以下代碼即可。

這裡只是個簡單的例子,其實我們可以做的更好,將進度條封裝為一個自定義控件,設計為一個通用 好看的進度條。這裡只講技術和方向,大家可以自己研究研究。

相關代碼:

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 ProgressBarSample
{
    //定義委托,異步調用
    delegate void ShowProgressDelegate(int totalStep, int currentStep);
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStart_Click(object sender, EventArgs e)
        {
            ParameterizedThreadStart start = new ParameterizedThreadStart(SetProgress);
            Thread progressThread = new Thread(start);
            progressThread.IsBackground = true;//標記為後台進程,在窗口退出時,正常退出
            progressThread.Start();
        }
        /// <summary>
        /// 設置當前進度
        /// </summary>
        /// <param name="state"></param>
        void SetProgress(object state)
        {
            for (int i = 1; i <= 100; i++)
            {
                Thread.Sleep(200);
                object[] objs = new object[] { 100, i };
                //異步調用
                this.Invoke(new ShowProgressDelegate(ShowProgress), objs);
            }
        }
        /// <summary>
        /// 刷新進度條
        /// </summary>
        /// <param name="totalStep"></param>
        /// <param name="currentStep"></param>
        void ShowProgress(int totalStep, int currentStep)
        {
            this.progressBar1.Maximum = totalStep;
            this.progressBar1.Value = currentStep;
    
            this.lbCurrent.Text = this.progressBar1.Value * 100 / progressBar1.Maximum + "%";
        }
    }
}

2、網絡扒蟲

經常遇到這樣的場景,通過扒蟲程序,去互聯網獲取所需資源。其實搜索引擎的一個重要組成部分就 是扒蟲。但是,往往扒蟲程序比較費時,這時就需要多線程幫忙。

這裡寫一個簡單的扒蟲程序,說明下原理。

案例:通過網絡連接,獲取網絡相關信息。

扒蟲對象:

using System;
using System.Net;
    
namespace Reptile
{
    public class NetReptile
    {
        /// <summary>
        /// 
        /// </summary>
        public string Url { get; set; }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        public NetReptile(string url)
        {
            this.Url = url;
        }
    
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public string GetContent()
        {
            WebClient client = new WebClient();
            return client.DownloadString(new Uri(this.Url));
        }
    }
}

抓到內容後,需要解析,提取我們需要的內容,這裡以抓取網頁的標題為例。解析器代碼:

using System;
using System.Text;
using System.Text.RegularExpressions;
    
namespace Reptile
{
    /// <summary>
    /// HTML解析器
    /// </summary>
    public class HtmlAnalyzer
    {
        /// <summary>
        /// 構造函數
        /// </summary>
        public HtmlAnalyzer()
        { }
        /// <summary>
        /// 獲取標題
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public string GetTitle(string html)
        {
            Regex regext = new Regex("(?<=<title>).*?(?=</title>)");
            Match m = regext.Match(html);
            if (m != null)
            {
                return m.ToString();                
            }
    
            return null;
        }
    
    }
}

查看本欄目

使用多線程創建扒蟲,抓取數據:

/// <summary>
        /// 多線程處理
        /// </summary>
        private void MultiThread()
        {
            string urls = tbUrl.Text;
            string[] separater = { "\r\n" };
            string[] urlList = urls.Split(separater, StringSplitOptions.RemoveEmptyEntries);
            int i = 1;
    
            foreach (var url in urlList)
            {
                Thread thread = new Thread(new ParameterizedThreadStart(Snap));
                thread.Name = "Thread" + i.ToString();
                thread.Start(url);
                i++;
            }
    
            //RefreshData();
        }
        /// <summary>
        /// 抓取數據
        /// </summary>
        /// <param name="state"></param>
        private void Snap(object state)
        {
            string url = state as string;
            NetReptile reptile = new NetReptile(url);
            string html = reptile.GetContent();
    
            if (!string.IsNullOrEmpty(html))
            {
                HtmlAnalyzer analyzer = new HtmlAnalyzer();
                string title = analyzer.GetTitle(html);
                Thread.Sleep(2000);
                this.Invoke(new AddItemDelegate(this.AddItem),title);                
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        private void AddItem(string item)
        {
            this.listData.Items.Add(item);
        }

全部源碼:http://files.cnblogs.com/yank/Reptile.rar

其他:

多線程應用還有很多,比如:文件上傳和下載、異步加載、Web請求、壓力測試、流水線技術等等。 後續我們還會將一些典型案例更新在這裡。

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