目录
public static void main()
{
//创建线程启动器(实际可以理解成一个限定,返回类型为void的广义委托)
ThreadStart start = new ThreadStart(ConsoleInformation);
//创建线程对象
Thread thread = new Thread(start);
//启动线程
thread.Start();
}
//子线程中要执行的耗时操作
public static void ConsoleInformation()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(string.Format("this is {0} time run in Thread A",i));
Thread.Sleep(500);
}
}
///
/// 利用Thread对象创建线程并执行
///
/// 该中方式不能传递参数进入线程,也没有办法指定线程完成后的事件回调或者获取线程结果
private void Base_btn_start_Click(object sender, EventArgs e)
{
//UI准备,是一个ListView型控件
UI_lv_content.Items.Clear();
//创建线程启动器(实际可以理解成一个限定,返回类型为void的广义委托)
ThreadStart start = new ThreadStart(UpdateListViewContent);
//创建线程对象
Thread thread = new Thread(start);
//启动线程
thread.Start();
}
//子线程具体要执行的耗时操作,因为操作中要修改UI,因此修改UI的操作必须由其他委托执行
private void UpdateListViewContent()
{
for (int i = 0; i < 5; i++)
{
//非异步洗发没有错,但异步就不能执行,否则需要修改夸线程修改标识
//this.UI_lv_content.Items.Add(string.Format("this is {0} time in Thread",i));
//取消或线程UI访问检查(非常不推荐!)
//Control.CheckForIllegalCrossThreadCalls = false;
//异步操作时,使用委托执行 , 判定是否控件在主线程外
if (UI_lv_content.InvokeRequired)
UI_lv_content.Invoke(new Del_UpdateListViewContentParam(Invoke_UpdateListViewContent), i);
else
Invoke_UpdateListViewContent();
}
}
//真正执行UI修改的功能函数的委托申明(带一个参数)
private delegate void Del_UpdateListViewContentParam(int i);
//真正执行UI修改的功能函数
private void Invoke_UpdateListViewContent(int i)
{
this.UI_lv_content.Items.Add(string.Format("this is {0} time in Thread param", i));
this.Update();
//模拟耗时操作
Thread.Sleep(500);
}
///
/// 采用对象作为委托函数的外壳,实现Thread方式的线程的参数传递
///
/// 该种方式有点类似于Java中继承Runnable的接口的做法,
/// 虽然该方法没有直接获取返回值,但可以通过强制监听Thread状态的方式处理线程完成的响应状态
private void UI_btn_start4_Click(object sender, EventArgs e)
{
CustomParam param=new CustomParam();
param.X = 12;
param.Y = 24;
ThreadStart start = new ThreadStart(param.RunInThread);
Thread thread = new Thread(start);
thread.Start();
//如果线程还在运行,则同步执行主线程操作,防止UI拥塞
while (thread.IsAlive)
Application.DoEvents();
//若线程完成操作了,则通过传递的类对象获取处理结果
UI_lv_content.Items.Clear();
UI_lv_content.Items.Add("finished : " + param.Coordinate);
UI_lv_content.Update();
}
//不带参数的委托(委托A)
private delegate void Del_UpdateListViewContent();
参数类申明
public class CustomParam
{
private int m_X;
private int m_Y;
private string m_coordinate;
//和delegate void Del_UpdateListViewContent()统一类型的方法
public void RunInThread()
{
m_coordinate = string.Format("({0},{1})", X, Y);
Thread.Sleep(1000);
}
//getter和setter省略
}
但若采用该种方式修改UI,则会将UI控件传递到参数类中,从而破坏结构化程序设计
///
/// 直接使用委托开启子线程
///
/// 该种方式没有显示创建Thread的过程,子线程由委托自身维护。
/// 改方式最大好处在于可以很方便的传递参数到线程中,同时可以获取线程的函数的处理结果
/// 但如果要处理修改UI的操作情况,则会出现委托中调用委托的操作,业务逻辑的复杂性
///
private void UI_btn_start3_Click(object sender, EventArgs e)
{
//UI准备
UI_lv_content.Items.Clear();
//依据UI判断如何处理主线程和子线程拥塞
is_Wait4Main = UI_ck_IsWaitMain2.Checked;
//直接创建委托-委托内容不修改UI
//Del_UpdateListViewContentAsyn del = new Del_UpdateListViewContentAsyn(Invoke_UpdateListViewContentAsyn);
//直接创建委托-委托内容修改UI;
Del_UpdateListViewContentAsyn del = new Del_UpdateListViewContentAsyn(Invoke_UpdateListViewContentAsynUI);
//执行委托,并依据委托类型传递参数
IAsyncResult iresult = del.BeginInvoke(10,12.1, null, null);
while (!iresult.IsCompleted)
Application.DoEvents();//该方式默认要处理UI拥塞,否则会出现UI锁死现象!
//获取委托结果
int result = del.EndInvoke(iresult);
//UI结果展示
//UI_lv_content.Items.Clear();
UI_lv_content.Items.Add("finished : " + result);
UI_lv_content.Update();
}
//带两个参数且觉有返回值的委托(委托C)
private delegate int Del_UpdateListViewContentAsyn(int max,double min);
//委托具体要执行的函数-不修改UI
private int Invoke_UpdateListViewContentAsyn(int max,double min)
{
Thread.Sleep(2000);
return new Random().Next(20);
}
为了在子线程运行过程中,不造成主线程拥塞,一定要对主线程拥塞进行处理
//委托具体要执行的函数-不修改UI
private int Invoke_UpdateListViewContentAsynUI(int max, double value)
{
//为委托内容中由以委托方式调用修改UI的委托-委托嵌套
for (int i = 0; i < 5; i++)
{
if (UI_lv_content.InvokeRequired)//委托具体执行方法中又再次调用了委托(具体修改执行过程见Thread对象,实例代码2)
UI_lv_content.Invoke(new Del_UpdateListViewContentParam(Invoke_UpdateListViewContent), i);
else
Invoke_UpdateListViewContent();
}
Thread.Sleep(2000);
return new Random().Next(20);
}
Thread thread = new Thread(start);
thread.Start();
while (thread.IsAlive)
Application.DoEvents();
IAsyncResult iresult = del.BeginInvoke(10,12.1, null, null);
while (!iresult.IsCompleted)
Application.DoEvents();
该对象使用非常类似于Android平台下AsynTask类
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged);
this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
具体的使用代码
private void UI_btn_start5_Click(object sender, EventArgs e)
{
//申明backgroundWorker1要上报进度报告
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.RunWorkerAsync();
//UI准备
UI_lv_content.Items.Clear();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//执行耗时操作
for (int i = 1; i < 11; i++)
{
Thread.Sleep(1000);
//发送修改UI请求
backgroundWorker1.ReportProgress(i,""+i);
}
//记录结果
e.Result = new Random().Next(25);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//处理子线程运行过程中,发出的进度请求,这里是可以修改UI的
UI_lv_content.Items.Add(String.Format("doing... {0}/10, value : {1}",e.ProgressPercentage,e.UserState.ToString()));
UI_lv_content.Update();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//获得子线程的处理结果
UI_lv_content.Items.Add("finish:"+e.Result);
}