中型项目中就会涉及到性能的问题。我主要是在C# winform中创建多个需要持续监听的事件后,会遇到性能的问题。这里面一般会遇到选择是多线程的方式还是异步的方式,有时候定时器创建多个后,也会导致性能变差。
单线程:就是一次只能做一件事。
点击炒菜后,只能等菜炒好了,才能做其他事【如下图:】
private void button1_Click(object sender, EventArgs e)
{
Thread.Sleep(3000);
MessageBox.Show("一盘菜炒好了【青椒土豆丝】","友情提示");
Thread.Sleep(5000);
MessageBox.Show("一盘菜炒好了【红烧肉】", "友情提示");
}
多线程:几乎同时完成多件事。
例如,一边炒菜,一边做饭。
private void button2_Click(object sender, EventArgs e)
{
Thread t = new Thread(() => {
Thread.Sleep(3000);
MessageBox.Show("一盘菜炒好了【青椒土豆丝】", "友情提示");
Thread.Sleep(5000);
MessageBox.Show("一盘菜炒好了【红烧肉】", "友情提示");
});
t.Start();
}
C#中较常用的方法,是任务类,下图就是任务开始执行的写法:
private void button3_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
Thread.Sleep(3000);
MessageBox.Show("一盘菜炒好了【青椒土豆丝】", "友情提示");
Thread.Sleep(5000);
MessageBox.Show("一盘菜炒好了【红烧肉】", "友情提示");
});
}
上面用一个Task,是需要花8秒做完青椒土豆丝和红烧肉。
可以用2个Task,让两盘菜同时做,只需要5秒钟。
private void button4_Click(object sender, EventArgs e)
{
Task.Run(() => {
Thread.Sleep(3000);
MessageBox.Show("一盘菜炒好了【青椒土豆丝】", "友情提示");
});
Task.Run(() => {
Thread.Sleep(5000);
MessageBox.Show("一盘菜炒好了【红烧肉】", "友情提示");
});
}
我们想两盘菜做好后再开始吃饭。下面的写法是否有问题呢:
private void button5_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
Thread.Sleep(3000);
MessageBox.Show("一盘菜炒好了【青椒土豆丝】", "友情提示");
Thread.Sleep(5000);
MessageBox.Show("一盘菜炒好了【红烧肉】", "友情提示");
});
MessageBox.Show("菜做好了,开始吃饭");
}
在Task前面添加await,让任务变为异步。此时方法名签名需要添加async。如下代码所示:
private async void button5_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
Thread.Sleep(3000);
MessageBox.Show("一盘菜炒好了【青椒土豆丝】", "友情提示");
Thread.Sleep(5000);
MessageBox.Show("一盘菜炒好了【红烧肉】", "友情提示");
});
MessageBox.Show("菜做好了,开始吃饭");
}
这样子,就实现了等炒菜这件事情完成后,再通知。
private async void button5_Click(object sender, EventArgs e)
{
await Task.Run(() => {
Thread.Sleep(3000);
MessageBox.Show("一盘菜炒好了【青椒土豆丝】", "友情提示");
});
await Task.Run(() => {
Thread.Sleep(5000);
MessageBox.Show("一盘菜炒好了【红烧肉】", "友情提示");
});
MessageBox.Show("菜做好了,开始吃饭");
}
创建Task类型的List类,然后将B需要开始执行的前置条件A都放入到列表中。
之后,等列表中的所有内容都完成后,开始执行B。
private void button5_Click(object sender, EventArgs e)
{
List<Task> ts = new List<Task>();
ts.Add(
Task.Run(() =>
{
Thread.Sleep(3000);
MessageBox.Show("一盘菜炒好了【青椒土豆丝】", "友情提示");
})
);
ts.Add(
Task.Run(() =>
{
Thread.Sleep(5000);
MessageBox.Show("一盘菜炒好了【红烧肉】", "友情提示");
})
);
Task.WhenAll(ts).ContinueWith(t =>
{
MessageBox.Show("菜做好了,开始吃饭");
});
}