[C#] 多线程(结合进度条)

线程生命周期(源w3cschool)

  1. 未启动状态:当线程实例被创建但Start方法未被调用时的状况。
  2. 就绪状态:当线程准备好运行并等待CPU周期时的状况。
  3. 不可运行状态
    • 已经调用Sleep方法
    • 已经调用Wait方法
    • 通过I/O操作阻塞
  4. 死亡状态:当线程已完成执行或已中止时的状况。

Thread常用方法:

  • public void Interrupt()    中断处于WaitSleepJoin线程状态的线程。
  • public void Join()           在继续执行标准的COM和SendMessage消息泵处理期间,阻塞调用线程,直到某个线程终止为止。
  • public void Start()          开始一个线程
  • public static void Sleep(int millisecondsTimeout)    让线程暂停一段时间

一 普通线程

分为两种,一种是不需要给子线程传参数,Thread t = new Thread(new ThreadStart(void () target)); 另一种是要给子线程传一个参数,Thread t = new Thread(new ParameterizedThreadStart(void (object) target));

  1 // 普通线程
  2 private void btn1_Click(object sender, EventArgs e)
  3 {
  4 	progressBar.Value = 0;
  5 	Thread tt = new Thread(new ThreadStart(DoWork1));
  6 	tt.Name = "不带参数普通线程";
  7 	tt.Start();
  8 	Thread t = new Thread(new ParameterizedThreadStart(DoWork2));
  9 	t.Name = "带参数普通线程";
 10 	t.IsBackground = true;
 11 	t.Start(100);
 12 	_msg += "当前线程的执行状态:" + t.IsAlive + "\r\n";
 13 	_msg += "当前托管线程的唯一标识:" + t.ManagedThreadId + "\r\n";
 14 	_msg += "线程名称:" + t.Name + "\r\n";
 15 	_msg += "当前线程的状态:" + t.ThreadState;
 16 	MessageBox.Show("消息:\r\n" + _msg, "提示", MessageBoxButtons.OK);
 17 }
 18 // 线程方法
 19 private void DoWork1()
 20 {
 21 	for (int i = 0; i < 100; i++)
 22 	{
 23 		// 跨线程访问UI,BeginInvoke采用异步委托
 24 		progressBar.BeginInvoke(new EventHandler((sender, e) =>
 25 		{
 26 			progressBar.Value = i;
 27 		}), null);
 28 	}
 29 }
 30 // 线程方法
 31 private void DoWork2(object obj)
 32 {
 33 	for (int i = 0; i < (int)obj; i++)
 34 	{
 35 		progressBar.BeginInvoke(new EventHandler((sender, e) =>
 36 		{
 37 			progressBar.Value = i;
 38 		}), null);
 39 	}
 40 }
 41 

普通线程

二  线程池

public static bool QueueUserWorkItem(WaitCallback);

public static bool QueueUserWorkItem(WaitCallback, object);

线程池默认为后台线程(IsBackground)

  1 private void btn3_Click(object sender, EventArgs e)
  2 {
  3 	ThreadPool.QueueUserWorkItem(DoWork2, 100);
  4 	// 或者
  5 	ThreadPool.QueueUserWorkItem((s) =>
  6 	{
  7 		int minWorkerThreads, minCompletionPortThreads, maxWorkerThreads, maxCompletionPortThreads;
  8 		ThreadPool.GetMinThreads(out minWorkerThreads, out minCompletionPortThreads);
  9 		ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxCompletionPortThreads);
 10 		MessageBox.Show(String.Format("WorkerThreads = {0} ~ {1}, CompletionPortThreads = {2} ~ {3}",
 11 			minWorkerThreads, maxWorkerThreads, minCompletionPortThreads, maxCompletionPortThreads));
 12 		DoWork2(100);
 13 	});
 14 }
 15 // 线程方法
 16 private void DoWork2(object obj)
 17 {
 18 	for (int i = 0; i < (int)obj; i++)
 19 	{
 20 		// Thread.Sleep(50);
 21 		progressBar.BeginInvoke(new EventHandler((sender, e) =>
 22 		{
 23 			progressBar.Value = i;
 24 		}), null);
 25 	}
 26 }
 27 

线程池

三  BackgroundWorker

  1 private void btn4_Click(object sender, EventArgs e)
  2 {
  3 	progressBar.Value = 0;
  4 	BackgroundWorker bw = new BackgroundWorker();
  5 	bw.WorkerReportsProgress = true;// 是否报告进度更新
  6 	// 线程执行
  7 	bw.DoWork += new DoWorkEventHandler((obj, args) =>
  8 	{
  9 		for (int i = 0; i < 100; i++)
 10 		{
 11 			bw.ReportProgress(i);
 12 		}
 13 	});
 14 	// UI主线程显示进度
 15 	bw.ProgressChanged += (obj, progressChangedEventArgs) =>
 16 	{
 17 		progressBar.Value = progressChangedEventArgs.ProgressPercentage;
 18 	};
 19 	// 线程执行完成后的回调函数
 20 	bw.RunWorkerCompleted += (obj, runWorkerCompletedEventArgs) =>
 21 	{
 22 		MessageBox.Show("子线程执行完成!");
 23 	};
 24 	if (!bw.IsBusy)
 25 	{
 26 		bw.RunWorkerAsync();
 27 	}
 28 }

BackgroundWorker

三  Task(.NET 4.0以上版本)

参考博客http://www.cnblogs.com/luxiaoxun/p/3280146.html

  1 private void btn5_Click(object sender, EventArgs e)
  2 {
  3 	progressBar.Value = 0;
  4 	Task<bool> t = new Task<bool>(maxValue => DoWork((int)maxValue), progressBar.Maximum);
  5 	t.Start();
  6 	t.Wait();
  7 	// 任务完成后继续延续任务
  8 	Task cwt = t.ContinueWith(task => MessageBox.Show("The result is " + t.Result));
  9 }
 10 // 线程方法
 11 private bool DoWork(int maxValue)
 12 {
 13 	for (int n = 0; n < maxValue; n++)
 14 	{
 15 		progressBar.BeginInvoke(new EventHandler((sender, e) =>
 16 		{
 17 			progressBar.Value = n;
 18 		}), null);
 19 	}
 20
 21 	return true;
 22 }
 23 

Task

四  异步委托

参考博客http://www.cnblogs.com/luxiaoxun/p/3280146.html

  1 public delegate string MyDelegate(object arg);
  2
  3 private void btn6_Click(object sender, EventArgs e)
  4 {
  5 	MyDelegate myDelegate = new MyDelegate(DoWork3);
  6 	IAsyncResult result = myDelegate.BeginInvoke(100, DoWork2Callback, "回调函数参数");
  7
  8 	// 异步执行完成
  9 	string resultStr = myDelegate.EndInvoke(result);
 10 }
 11
 12 // 线程函数
 13 private string DoWork3(object arg)
 14 {
 15 	for (int n = 0; n < (int)arg; n++)
 16 	{
 17 		progressBar.BeginInvoke(new EventHandler((sender, e) =>
 18 		{
 19 			progressBar.Value = n;
 20 		}), null);
 21 	}
 22
 23 	return "Finished";
 24 }
 25
 26 // 异步回调函数
 27 private void DoWork2Callback(IAsyncResult arg)
 28 {
 29 	MessageBox.Show(arg.AsyncState.ToString());
 30 }

异步委托

五  附 跨线程访问UI之 SynchronizationContext (同步上下文)

  1 private void btn2_Click(object sender, EventArgs e)
  2 {
  3 	SynchronizationContext context = SynchronizationContext.Current;
  4 	new Thread(() =>
  5 	{
  6 		for (int i = 0; i < 100; i++)
  7 		{
  8 			// Send方法是发送一个异步请求消息
  9 			//context.Send((s) =>
 10 			//{
 11 			//	progressBar.Value = i;
 12 			//}, null);
 13 			// Post方法是发送一个同步请求消息
 14 			context.Post((s) =>
 15 			{
 16 				progressBar.Value = i;
 17 			}, null);
 18 		}
 19 	}).Start();
 20 }
 21 

SynchronizationContext

六  资源下载

源代码工程下载:http://files.cnblogs.com/files/memento/ThreadDemo.zip (注,工程中包含Silverlight的多线程实例项目,在运行测试时将Winform的工程设置为启动项目即可;如果电脑上没有安装Silverlight,则可以将Silverlight多线程实例工程卸载掉即可)

七  参考资料:

☆多线程讲解 http://www.w3cschool.cc/csharp/csharp-multithreading.html

http://www.cnblogs.com/luxiaoxun/p/3280146.html

时间: 2024-10-13 23:34:48

[C#] 多线程(结合进度条)的相关文章

安卓 下载多线程带进度条

当我们学完java中多线程的下载后,可以将它移植到我们的安卓中来,下面是具体实现源码: DownActivity.java [java] view plaincopy package com.example.downloads; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.Ma

c#多线程,进度条,实时给前台发送数据

///做了一个wpf多线程,在实际场景中利用多线程保证程序不会卡死,性能上有所提高 //启动线程处理                Thread thread1 = new Thread(UpdateBtn);                thread1.IsBackground = true;//设置为后台线程,当主线程结束后,后台线程自动退出,否则不会退出程序不能结束                thread1.Start(); private void UpdateBtn()     

[转] 实现winfrom进度条及进度信息提示,winfrom程序假死处理

china_xuhua 原文地址 1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线 程,如果不采用多线程控制进度条,窗口很容易假死(无法适时看到进度信息).下面我就简单结合一个我写的例子给大家做一个介绍. 第一步:设计界面,注意需要引用 using System.Threading; 控件名称分别为: progressBar1:label1:textBox1:button1: 第二

android 14 进度条和拖动条

进度条: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ProgressBar 默认进度条 andr

实现winfrom进度条及进度信息提示,winfrom程序假死处理

1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口很容易假死(无法适时看到进度信息).下面我就简单结合一个我写的例子给大家做一个介绍. 第一步:设计界面,注意需要引用 using System.Threading; 控件名称分别为: progressBar1:label1:textBox1:button1: 第二步:定义一个代理,用于更新Progr

C#winform使用进度条

在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口很容易假死(无法适时看到进度信息).下面我就简单结合一个我写的例子给大家做一个介绍.第一步:设计界面不说了...注意需要引用 using System.Threading;第二步:定义一个代理,用于更新ProgressBar的值(Value) //更新进度列表 private delegate void SetPos(int ip

C#多线程进度条

public class ZyjProgressBar : System.Windows.Forms.ProgressBar { //用于跨线程访问控件的委托 private delegate void deleByControl(int v); //用于执行的任务 public Action Task { get; set; } private Thread taskThread; private deleByControl setValueDele; public ZyjProgressBa

C# 通过线程来控制进度条(转)--讲解多线程对界面的操作

// 通过创建委托解决传递参数问题 private void _btnRun_Click( object sender, System.EventArgs e ) { RunTaskDelegate runTask = new RunTaskDelegate( RunTask ); // 委托同步调用方式 runTask( Convert.ToInt16( _txtSecond.Value ) ); } //通过创建委托解决传递参数问题,通过委托的异步调用消除用户界面线程的阻塞问题 privat

JAVA程序设计(17)----- 制作文件拷贝软件 进程 输入流输出流 NIO 进度条 底层拷贝 多线程

使用NIO对文件进行底层拷贝(按照字节)多线程技术初级应用 不阻塞程序运行 package com.lovo.homework01; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import