线程是程序中顺序执行的流程,一个进程可以由多个线程组成,给个线程都可能单独执行
- 创建线程和停止线程
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace threadproj
{
class Program
{
static void Main(string[] args)
{
//Thread类创建并控制线程,该类的构造函数接受ThreadStart委托,该委托包装希望作为单独线程运行的函数
Thread t = new Thread(new ThreadStart( Dosomething));
t.Start();//启动线程
Console.WriteLine("continue with the execution...");//主线程执行的输出
while (!t.IsAlive) ;
Thread.Sleep(1);//目的可以为Dosomething()函数提供执行的机会
t.Abort();//停止线程
Console.ReadLine();
}
static void Dosomething()
{
try
{
while (true)
{
Console.WriteLine("Doing something...");
}
}
catch (ThreadAbortException ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
可以向线程传递形参
一是在类中包装函数,并且通过特性传入形参
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace threadproj
{
class Program
{
static void Main(string[] args)
{
Someclass sc = new Someclass();
sc.msg = "helloworld";
Thread t = new Thread( new ThreadStart( sc.Dosomething));
t.Start();
Console.ReadLine();
}
class Someclass
{
public string msg { get; set; }
public static void Dosomething()
{
try
{
while (true)
{
Console.WriteLine("Doing something...{0}",msg);
}
}
catch (ThreadAbortException ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
}
二是使用ParameterizedThreadStart委托而非ThreadStart委托
public static void Dosomething()
{
try
{
while (true)
{
Console.WriteLine("Doing something...{0}",msg);
}
}
catch (ThreadAbortException ex)
{
Console.WriteLine(ex.Message);
}
}
static void Main(string[] args)
{
Thread t = new Thread( new ParameterizedThreadStart( Dosomething));
t.Start("helloworld");//用start()方法传递实参
Console.ReadLine();
}
- 线程同步问题
1.使用Interlocked类 主要用于多个线程共享的变量执行原子操作
2.lock关键字
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace threadproj
{
class Program
{
static int num = 500;
static object obj = new object();
static void Main(string[] args)
{
Thread t1 = new Thread(new ThreadStart(Debit));
t1.Start();
Thread t2 = new Thread( new ThreadStart( Credit));
t2.Start();
Console.ReadLine();
}
static void Credit()
{
for (int i = 0; i < 15;i++ )
{
lock(obj)
{
num += 100;
Console.WriteLine("After credit ,num is " + num);
}
}
}
static void Debit()
{
for (int i = 0; i < 10; i++)
{
lock (obj)
{
num -= 100;
Console.WriteLine("After dedit ,num is " + num);
}
}
}
}
}
3.Monitor类
lock (obj)
{
num -= 100;
Console.WriteLine("After dedit ,num is " + num);
}
等价于Monitor.Enter(obj);
num -= 100;
Console.WriteLine("After dedit ,num is " + num);
Monitor.Exit(obj);
- Winform 中BackgroundWorker组件的应用
添加控件如下描述
private System.ComponentModel.BackgroundWorker backgroundWorker1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtNum;
private System.Windows.Forms.Label lb1Result;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnStart;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ProgressBar progressBar1;
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;
namespace backgroundworkerproj
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
lb1Result.Text = string.Empty;//显示结果的标签清空
btnCancel.Enabled = true;
btnStart.Enabled = false;
progressBar1.Value = 0;//进度条初始为0
backgroundWorker1.RunWorkerAsync(txtNum.Text);//开始执行后台操作
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker)sender;//在单线程上执行操作
e.Result = sunnumbers(double.Parse(e.Argument.ToString()), worker, e);//获取异步操作结果的值
}
//求和函数 返回sum
private double sunnumbers(double number,BackgroundWorker worker,DoWorkEventArgs e)
{
int lastpercent = 0;
double sum = 0;
for (double i = 0; i <= number;i++ )
{
if (worker.CancellationPending)//指示应用程序是否已经请求取消后台操作 返回bool值
{
e.Cancel = true;
}
else
{
sum += i;
if(i%10==0)
{
int percentdone = (int)((i / number) * 100);
if (percentdone>lastpercent)
{
worker.ReportProgress(percentdone);
lastpercent = percentdone;
}
}
}
}
return sum;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
lb1Result.Text = e.ProgressPercentage.ToString() + "%";
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error!=null)
{
MessageBox.Show(e.Error.Message);
}
else if(e.Cancelled)
MessageBox.Show("canceled");
else
{
lb1Result.Text = "Sum of 1 to "+txtNum.Text +"is "+e.Result;
}
btnStart.Enabled = true;
btnCancel.Enabled = false;
}
private void btnCancel_Click(object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
btnCancel.Enabled = false;
}
}
}