一、随机进度条状态-线程池线程
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Multithreading_Csharp_Winform
{
//线程池线程演示
public partial class Form1 : Form
{
List<ProgressBar> progressBars;
bool started;
public Form1()
{
InitializeComponent();
progressBars = new List<ProgressBar>();
started = false;
}
//开始 前先生成进度条
private void button2_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
if (button.Text == "start")
{
buttonGenerateProgressBars.Enabled = false;
button.Text = "stop";
started = true;
foreach (ProgressBar progressBar in progressBars)
{
//将方法排队以供执行,并指定包含该方法要使用的数据的对象。该方法在线程池线程变为可用时执行。
ThreadPool.QueueUserWorkItem(StartBar, progressBar);//
}
}
else
{
buttonGenerateProgressBars.Enabled = true;
button.Text = "start";
started = false;
}
}
//线程池线程的方法:state为传入的 进度条对象
private void StartBar(object state)
{
ProgressBar progressBar = (ProgressBar)state;//拆箱
Random random = new Random();
while (started)
{
this.Invoke(new Action(()=> {
progressBar.Value = random.Next(0, 100);//随机状态条值
}));
Thread.Sleep(600);
}
}
//生成进度条
private void buttonGenerateProgressBars_Click(object sender, EventArgs e)
{
//移除所有进度条
if (progressBars.Count > 0)
{
foreach (ProgressBar progressBar in progressBars)
{
this.Controls.Remove(progressBar);
}
progressBars.Clear();
}
int count = Convert.ToInt32(numericUpDown1.Value);//进度条数
int num1;//可用的工作线程数。
int available;//可用的异步I/O线程数
//检索System.Threading.ThreadPool.GetMaxThreads(System.Int32@,System.Int32@)方法返回的最大线程池线程数与当前活动的线程数之间的差值
ThreadPool.GetAvailableThreads(out num1, out available);
//在切换到管理线程创建和销毁的算法之前,设置线程池在发出新请求时按需创建的最小线程数。
ThreadPool.SetMinThreads(count, available);//线程池按需创建的最小工作线程数 count 线程池按需创建的最小异步I/O线程数available
int yCoord = 50;
int xCoord = 10;
bool rightToLeft = false;
Random random = new Random();
//创建进度条
for (int i = 0; i < count; i++)
{
ProgressBar progressBar = new ProgressBar();
progressBar.Width = 700;
progressBar.Height = 23;
progressBar.Top = yCoord;
progressBar.Left = xCoord;
if (rightToLeft)
{
progressBar.RightToLeft = RightToLeft.Yes;
//获取或设置一个值,该值指示是否从右向左显示System.Windows.Forms.ProgressBar及其包含的任何文本。
progressBar.RightToLeftLayout = rightToLeft;
rightToLeft = false;
}
else
{
rightToLeft = true;
}
progressBar.SetState(random.Next(0, 4));//设置进度条随机位置
this.Controls.Add(progressBar);//显示控件
yCoord = progressBar.Top + 23;//更新进度条位置y
progressBars.Add(progressBar);//添加到进度条列表
}
}
//下一演示
private void button1_Click(object sender, EventArgs e)
{
HorseRacing horseRacing = new HorseRacing();
this.Visible = false;
started = false;
horseRacing.ShowDialog();
this.Close();
}
}
}
二、进度条比赛-线程池线程
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace Multithreading_Csharp_Winform
{
public partial class HorseRacing : Form
{
List<ProgressBar> progressBars;
bool won;
public HorseRacing()
{
InitializeComponent();
won = true;
progressBars = new List<ProgressBar>() { Horse1, Horse2, Horse3, Horse4, Horse5 };//进度条列表
int i = 1;
foreach (ProgressBar progressBar in progressBars)
{
progressBar.Name = $"Horse {i++}";//重命名进度条
}
int num1;
int available;
ThreadPool.GetAvailableThreads(out num1, out available);
//在切换到管理线程创建和销毁的算法之前,设置线程池在发出新请求时按需创建的最小线程数。
ThreadPool.SetMinThreads(5, available);
}
//开始/结束
private void button2_Click(object sender, EventArgs e)
{
if (!won)
{
won = true;//赢了
MessageBox.Show("Stopped");
}
else//
{
won = false;
foreach (ProgressBar progressBar in progressBars)
{
progressBar.Value = 0;//重置进度条的值
}
foreach (ProgressBar progressBar in progressBars)
{
ThreadPool.QueueUserWorkItem(StartRace, progressBar);//进度条比赛线程
}
}
}
//开始比赛
private void StartRace(object state)
{
ProgressBar progressBar = (ProgressBar)state;
Random random = new Random();
int speed;
int num;
while (!won)
{
speed = random.Next(20);
num = progressBar.Value + random.Next(0, speed);
this.Invoke(new Action(()=> {
progressBar.Value = (num > 100 ? 100 : num);
}));
Thread.Sleep(500);
if (progressBar.Value == 100)//有进度条满了
{
won = true;
MessageBox.Show($"{progressBar.Name} won!");
}
}
}
//下一演示
private void button1_Click(object sender, EventArgs e)
{
Fiponachi fiponachi = new Fiponachi();
this.Visible = false;
won = true;
fiponachi.ShowDialog();
this.Close();
}
}
}
三、计算斐波那契数列满足指定条件时的个数--异步任务
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Multithreading_Csharp_Winform
{
public partial class Fiponachi : Form
{
public Fiponachi()
{
InitializeComponent();
}
//斐波那契数列指的是这样一个数列:1,1,2,3,5,8,13,21,34,55,89...
public Task<int> FibAsync(int stopNum)
{
int tmp;
int numbers = 0;
for (int firstNum = 0, secNum = 1; secNum + firstNum <= stopNum; numbers++)
{
tmp = secNum;
secNum += firstNum;
firstNum = tmp;
}
return Task.FromResult(numbers);//返回Task<TResult>
}
//异步方法:
private async void button2_Click(object sender, EventArgs e)
{
int res = await FibAsync(Convert.ToInt32(numericUpDown1.Value));//等待任务返回
MessageBox.Show($"Result: {res}!");
}
//下一演示
private void button1_Click(object sender, EventArgs e)
{
FindWordFile findWordFile = new FindWordFile();
this.Visible = false;
findWordFile.ShowDialog();
this.Close();
}
}
}
四、在文件内容里查找word--异步读取文件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Multithreading_Csharp_Winform
{
public partial class FindWordFile : Form
{
string path;
public FindWordFile()
{
InitializeComponent();
path = String.Empty;
}
//选择路径文件
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "All files(*.*)|*.*";
if (ofd.ShowDialog() != DialogResult.Cancel)
{
label1.Text = $"path: {ofd.FileName}";
path = ofd.FileName;
}
}
//开始 异步读取文件内容
private void button2_Click(object sender, EventArgs e)
{
if (path == String.Empty)
{
MessageBox.Show("Choose file");
return;
}
string result;
using (FileStream fs = new FileStream(path, FileMode.Open))//打开文件
{
byte[] arr = new byte[fs.Length];
//开始异步读取操作。请考虑改用System.IO.FileStream.ReadAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)。
IAsyncResult asyncResult = fs.BeginRead(arr, 0, arr.Length, null, null);
//等待挂起的异步读取操作完成。(请考虑改用System.IO.FileStream.ReadAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)。)
fs.EndRead(asyncResult);
result = Encoding.UTF8.GetString(arr);
}
MessageBox.Show($"Find: {result.Split($"{textBox1.Text}").Length - 1}");//用要查找的word 来分割内容
}
//下一演示
private void button3_Click(object sender, EventArgs e)
{
FindWordDir findWordDir = new FindWordDir();
this.Visible = false;
findWordDir.ShowDialog();
this.Close();
}
}
}
五、在文件夹下查找包含word的文件--线程池线程、异步IO
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Multithreading_Csharp_Winform
{
public partial class FindWordDir : Form
{
string path;//文件夹
bool stop;
int filesInProcessing;
public FindWordDir()
{
InitializeComponent();
stop = true;
filesInProcessing = 0;//正在处理的文件数
label3.Text = String.Empty;
}
//选择文件夹
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
if (folderBrowserDialog.ShowDialog() != DialogResult.Cancel)
{
label1.Text = $"path: {folderBrowserDialog.SelectedPath}";
path = folderBrowserDialog.SelectedPath;
}
}
//开始
private void button2_Click(object sender, EventArgs e)
{
if (path == String.Empty)
{
MessageBox.Show("Choose folder");
return;
}
else if (stop == false && filesInProcessing != 0)
{
MessageBox.Show("Finding word");
}
stop = false;
//在线程池上运行任务
Task.Run(() =>
{
FindWordInFolder(path);//在目录里查找
label3.Text = "Search in progress..";
while (true)
{
if (stop)
{
while (filesInProcessing > 0)
{
//查找中
}
//所有文件都遍历完后
label3.Text = "Done";
break;
}
}
});
}
//在文件夹查找包含textBox1.Text的文件
private void FindWordInFolder(object state)
{
string dirPath = (string)state;
IEnumerable<string> directories = Directory.EnumerateDirectories(dirPath);//文件夹爱下的所有目录
IEnumerable<string> files = Directory.EnumerateFiles(dirPath);//文件夹下所有文件路径
foreach (string folderPath in directories)
{
ThreadPool.QueueUserWorkItem(FindWordInFolder, folderPath);//在文件夹里查找内容
}
foreach (string filePath in files)
{
ThreadPool.QueueUserWorkItem(FindWordInFile, filePath);//在文件里查找内容
Interlocked.Increment(ref filesInProcessing);//递增指定的变量并将结果存储为原子操作。
}
stop = true;
}
//在文件里查找内容textBox1.Text
private void FindWordInFile(object state)
{
string filePath = (string)state;
try
{
//读取文件内容
string result;
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
byte[] arr = new byte[fs.Length];
IAsyncResult asyncResult = fs.BeginRead(arr, 0, arr.Length, null, null);
fs.EndRead(asyncResult);
result = Encoding.UTF8.GetString(arr);
}
//查找word
int count = result.Split($"{textBox1.Text}").Length - 1;
string[] str = result.Split($"{textBox1.Text}");
if (count > 0)
{
lock (textBox2)
{
textBox2.Text += $"Found: {count} \"{textBox1.Text}\" in {filePath}\r\n";//在某个文件中找到该内容多少次
}
}
}
catch (Exception)
{
MessageBox.Show($"Error while reading file: {filePath}");
}
finally
{
Interlocked.Decrement(ref filesInProcessing);
}
}
}
}
进度条状态设置方法:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace Multithreading_Csharp_Winform
{
public static class ModifyProgressBarColor
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);
public static void SetState(this ProgressBar pBar, int state)//设置 进度条状态
{
SendMessage(pBar.Handle, 1040, (IntPtr)state, IntPtr.Zero);
}
}
}
The End