[C#] 多线程总结(结合进度条)
Posted zhaoshujie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[C#] 多线程总结(结合进度条)相关的知识,希望对你有一定的参考价值。
线程生命周期
- 未启动状态:当线程实例被创建但 Start 方法未被调用时的状况。
- 就绪状态:当线程准备好运行并等待 CPU 周期时的状况。
- 不可运行状态:
- 已经调用 Sleep 方法
- 已经调用 Wait 方法
- 通过 I/O 操作阻塞
- 死亡状态:当线程已完成执行或已中止时的状况。
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));
// 普通线程 private void btn1_Click(object sender, EventArgs e) { progressBar.Value = 0; Thread tt = new Thread(new ThreadStart(DoWork1)); tt.Name = "不带参数普通线程"; tt.Start(); Thread t = new Thread(new ParameterizedThreadStart(DoWork2)); t.Name = "带参数普通线程"; t.IsBackground = true; t.Start(100); _msg += "当前线程的执行状态:" + t.IsAlive + " "; _msg += "当前托管线程的唯一标识:" + t.ManagedThreadId + " "; _msg += "线程名称:" + t.Name + " "; _msg += "当前线程的状态:" + t.ThreadState; MessageBox.Show("消息: " + _msg, "提示", MessageBoxButtons.OK); } // 线程方法 private void DoWork1() { for (int i = 0; i < 100; i++) { // 跨线程访问 UI,BeginInvoke 采用异步委托 progressBar.BeginInvoke(new EventHandler((sender, e) => { progressBar.Value = i; }), null); } } // 线程方法 private void DoWork2(object obj) { for (int i = 0; i < (int)obj; i++) { progressBar.BeginInvoke(new EventHandler((sender, e) => { progressBar.Value = i; }), null); } }
二 线程池
public static bool QueueUserWorkItem(WaitCallback);
public static bool QueueUserWorkItem(WaitCallback, object);
线程池默认为后台线程(IsBackground)
private void btn3_Click(object sender, EventArgs e) { ThreadPool.QueueUserWorkItem(DoWork2, 100); // 或者 ThreadPool.QueueUserWorkItem((s) => { int minWorkerThreads, minCompletionPortThreads, maxWorkerThreads, maxCompletionPortThreads; ThreadPool.GetMinThreads(out minWorkerThreads, out minCompletionPortThreads); ThreadPool.GetMaxThreads(out maxWorkerThreads, out maxCompletionPortThreads); MessageBox.Show(String.Format("WorkerThreads = {0} ~ {1}, CompletionPortThreads = {2} ~ {3}", minWorkerThreads, maxWorkerThreads, minCompletionPortThreads, maxCompletionPortThreads)); DoWork2(100); }); } // 线程方法 private void DoWork2(object obj) { for (int i = 0; i < (int)obj; i++) { // Thread.Sleep(50); progressBar.BeginInvoke(new EventHandler((sender, e) => { progressBar.Value = i; }), null); } }
三 BackgroundWorker
private void btn4_Click(object sender, EventArgs e) { progressBar.Value = 0; BackgroundWorker bw = new BackgroundWorker(); bw.WorkerReportsProgress = true;// 是否报告进度更新 // 线程执行 bw.DoWork += new DoWorkEventHandler((obj, args) => { for (int i = 0; i < 100; i++) { bw.ReportProgress(i); } }); // UI主线程显示进度 bw.ProgressChanged += (obj, progressChangedEventArgs) => { progressBar.Value = progressChangedEventArgs.ProgressPercentage; }; // 线程执行完成后的回调函数 bw.RunWorkerCompleted += (obj, runWorkerCompletedEventArgs) => { MessageBox.Show("子线程执行完成!"); }; if (!bw.IsBusy) { bw.RunWorkerAsync(); } }
三 Task(.NET 4.0以上版本)
参考博客 http://www.cnblogs.com/luxiaoxun/p/3280146.html
private void btn5_Click(object sender, EventArgs e) { progressBar.Value = 0; Task<bool> t = new Task<bool>(maxValue => DoWork((int)maxValue), progressBar.Maximum); t.Start(); t.Wait(); // 任务完成后继续延续任务 Task cwt = t.ContinueWith(task => MessageBox.Show("The result is " + t.Result)); } // 线程方法 private bool DoWork(int maxValue) { for (int n = 0; n < maxValue; n++) { progressBar.BeginInvoke(new EventHandler((sender, e) => { progressBar.Value = n; }), null); } return true; }
四 异步委托
参考博客 http://www.cnblogs.com/luxiaoxun/p/3280146.html
public delegate string MyDelegate(object arg); private void btn6_Click(object sender, EventArgs e) { MyDelegate myDelegate = new MyDelegate(DoWork3); IAsyncResult result = myDelegate.BeginInvoke(100, DoWork2Callback, "回调函数参数"); // 异步执行完成 string resultStr = myDelegate.EndInvoke(result); } // 线程函数 private string DoWork3(object arg) { for (int n = 0; n < (int)arg; n++) { progressBar.BeginInvoke(new EventHandler((sender, e) => { progressBar.Value = n; }), null); } return "Finished"; } // 异步回调函数 private void DoWork2Callback(IAsyncResult arg) { MessageBox.Show(arg.AsyncState.ToString()); }
五 附 跨线程访问UI之 SynchronizationContext (同步上下文)
private void btn2_Click(object sender, EventArgs e) { SynchronizationContext context = SynchronizationContext.Current; new Thread(() => { for (int i = 0; i < 100; i++) { // Send方法是发送一个异步请求消息 //context.Send((s) => //{ // progressBar.Value = i; //}, null); // Post方法是发送一个同步请求消息 context.Post((s) => { progressBar.Value = i; }, null); } }).Start(); }
六 参考资料:
☆多线程讲解 http://www.w3cschool.cc/csharp/csharp-multithreading.html
☆http://www.cnblogs.com/luxiaoxun/p/3280146.html
以上是关于[C#] 多线程总结(结合进度条)的主要内容,如果未能解决你的问题,请参考以下文章