WinForm中UI假死的解决方法
https://www.codenong.com/cs106719464/WinForm中的UI假死其实是个老生常谈的问题了,但最近还是很多人问我该如何解决,所以今天就来说明一下如何解决UI假死的问题。实验程序界面如下图所示:
方法一:async + await + Task
首先看下面一段代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// 开始
private void btnStart_Click(object sender, EventArgs e)
{
string message = GetMessage();
MessageBox.Show(message);
}
// 一个耗时任务
private string GetMessage()
{
Thread.Sleep(10000);
return "Hello World";
}
}
}
在上面的代码中,GetMessage()方法耗时10秒钟,如果你点击按钮,那么在10秒钟内窗体将处于假死状态。这种情况很常见,之所以会造成UI假死的原因也很简单:某个函数耗时太久。在遇见这种情况的时候,我们就可以考虑使用async + await + Task来解决,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// 开始
private async void btnStart_Click(object sender, EventArgs e)
{
string message = await GetMessage();
MessageBox.Show(message);
}
// 一个耗时任务
private async Task GetMessage()
{
return await Task.Run(() =>
{
Thread.Sleep(10000);
return "Hello World";
});
}
}
}运行之后点击按钮,你会发现UI没有假死,窗体可以随意拖动了。
方法二:使用BackgroundWorker组件
在很多时候,我们需要动态显示当前的程序执行进度,以便让用户了解程序已经执行到哪一步了。很多同志都会这么写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// 开始
private void btnStart_Click(object sender, EventArgs e)
{
int max = pgbStatus.Maximum;
for (int i = 1; i
页:
[1]