zoukankan      html  css  js  c++  java
  • [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 + "
    ";
     13 	_msg += "当前托管线程的唯一标识:" + t.ManagedThreadId + "
    ";
     14 	_msg += "线程名称:" + t.Name + "
    ";
     15 	_msg += "当前线程的状态:" + t.ThreadState;
     16 	MessageBox.Show("消息:
    " + _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://www.w3cschool.cc/csharp/csharp-multithreading.html

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

  • 相关阅读:
    安卓手机抓包
    探讨 yum 与 rpm 的安装包数量
    CentOS6.5 yum安装桌面环境
    CentOS6.5使用本地光盘做yum源 (参考:http://www.jb51.net/os/RedHat/43343.html)
    tar、zip 、unzip 打包与压缩 (参考:http://pengyl.blog.51cto.com/5591604/1191197)
    CentOS6.5使用本地光盘做yum源 (参考:http://www.jb51.net/os/RedHat/43343.html)
    mount 挂载光盘
    Shell编程
    Vim实现批量注释的方法
    Linux基本命令
  • 原文地址:https://www.cnblogs.com/memento/p/4333242.html
Copyright © 2011-2022 走看看