C#的所有异步多线程都是对Thread对象的封装。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(ThreadInvoke);
thread.Start();
}
private void ThreadInvoke()
{
Console.WriteLine("Thread is running.");
}
}
运行结果:
2. 也可以使用Lambda表达式代替执行方法,运行结果与上面例子一样。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread thread = new Thread(() =>
{
Console.WriteLine("Thread is running.");
});
thread.Start();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadStart threadStart = new ThreadStart(ThreadInvoke);
Thread thread = new Thread(threadStart);
thread.Start();
}
private void ThreadInvoke()
{
Console.WriteLine("Thread is running.");
}
}
4.IsBackground属性,可以设置该线程是否和主线程一起关闭;设置为false,当主线程关闭后,该线程还会运行,可以使用此特性进行一些关闭工作的资源释放。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(ThreadPoolInvoke, "This is First.");
// 线程池中只要有可用的线程,立刻调用
ThreadPool.QueueUserWorkItem((o) =>
{
Console.WriteLine("线程ID:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(o.ToString());
}, "This is Second.");
}
private void ThreadPoolInvoke(object o)
{
Console.WriteLine("线程ID:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(o.ToString());
}
}
运行结果:
2. 线程池通过SetMaxThreads和GetMaxThreads设定和获取线程中最大的工作线程数量
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(ThreadPoolInvoke, "This is First.");
ThreadPool.SetMinThreads(20, 16);
ThreadPool.SetMaxThreads(20, 16);
ThreadPool.GetMaxThreads(out int mW, out int mC);
Console.WriteLine(mW + "----" + mC);
}
private void ThreadPoolInvoke(object o)
{
Console.WriteLine("线程ID:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(o.ToString());
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private ManualResetEvent manualResetEvent = new ManualResetEvent(false);
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(ThreadPoolInvoke, null);
// 阻止主线程继续执行,将主线程设置为等待线程,等待异步线程的执行情况。
// 如果异步线程中,不设置manualResetEvent.Set();则该线程一直等待中,主线程陷入卡死状态。
manualResetEvent.WaitOne();
Console.WriteLine("World.");
}
private void ThreadPoolInvoke(object o)
{
Console.WriteLine("Hello ");
// 允许等待线程WaitOne后的代码可以继续执行;如果没有这句代码,主线程一直因为WaitOne而等待。
this.manualResetEvent.Set();
}
}
Task的异步线程调用
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private ManualResetEvent manualResetEvent = new ManualResetEvent(false);
private void button1_Click(object sender, EventArgs e)
{
// 直接调用
Task.Run(TaskInvoke);
// 利用匿名委托调用
Task.Run(delegate ()
{
Console.WriteLine("This is anonymous delegate invoke.");
});
// 利用Lambda表达式调用
Task.Run(() =>
{
Console.WriteLine("This is noraml invoke.");
});
// 常规的调用方法
Task task = new Task(TaskInvoke);
task.Start();
// 工厂模式调用
TaskFactory taskFactory = new TaskFactory();
taskFactory.StartNew(TaskInvoke);
taskFactory.StartNew(() => { });
taskFactory.StartNew(delegate () { });
}
private void TaskInvoke()
{
Console.WriteLine("This is delegate invoke.");
}
}
1.如果不控制同步,则主线的后续代码执行顺序并不固定:
private void button1_Click(object sender, EventArgs e)
{
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
Console.WriteLine("OK");
}
private void TaskInvoke()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
两次运行结果:
2. 利用WhenAll方法和ContinueWith方法,所有子线程执行完毕后,才会执行ContinueWith方法中的委托
private void button1_Click(object sender, EventArgs e)
{
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
Task.WhenAll(tasks).ContinueWith((o) => { Console.WriteLine("OK"); });
}
private void TaskInvoke()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
}
private void button1_Click(object sender, EventArgs e)
{
List<Task> tasks = new List<Task>();
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
tasks.Add(Task.Run(() => { this.TaskInvoke(); }));
Task.WaitAny(tasks.ToArray());
Console.WriteLine("OK");
}
private void TaskInvoke()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
运行结果:
4. 如果需要阻塞主线程,等待所有子线程都运行完毕,再运行主线程,使用WaitAll方法。用法和WaitAny类似。其功能和await类似,但await不会阻塞主线程,因为await之后的代码会放到一个子线程里面去执行,所以主线程不会等待阻塞。
private void button1_Click(object sender, EventArgs e)
{
Parallel.Invoke(
() => { Console.WriteLine(Thread.CurrentThread.ManagedThreadId); },
() => { Console.WriteLine(Thread.CurrentThread.ManagedThreadId); },
() => { Console.WriteLine(Thread.CurrentThread.ManagedThreadId); });
}
private void button1_Click(object sender, EventArgs e)
{
ParallelOptions parallelOptions = new ParallelOptions();
//允许的最大并发数量
parallelOptions.MaxDegreeOfParallelism = 5;
// 一共产生10个并发,0是起始值,10是最大计数值,i是每次的计数
// 虽然是10个并发,但是按设置每次并发5个
Parallel.For(0, 10, parallelOptions, (i) =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
});
}
3.ForEach并发
private void button1_Click(object sender, EventArgs e)
{
ParallelOptions parallelOptions = new ParallelOptions();
//允许的最大并发数量
parallelOptions.MaxDegreeOfParallelism = 5;
// string[]数组作为参数,每个并发都会把string[]数组里面的一个成员传入线程执行
Parallel.ForEach(new string[] { "go", "run" }, parallelOptions, c =>
{
Console.WriteLine(c);
});
}