多線程應用很廣泛,簡單總結了一下:
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請求、壓力測試、流水線技術等等。 後續我們還會將一些典型案例更新在這裡。