在我们平时的开发中,有使用需要执行有些比较耗时的任务(比如说插入10000条数据到数据库或进行一些比较常时间的IO操作),如果我们在主线程中直接执行该任务的话,可能会使整个界面处于假死状态.这对用户来说是一个很不好的体验,作为一个合格的程序员,绝对不能停留在“程序能用就行”的境界,而是应该充分考虑用户的体验以及界面的友好性,把软件做成一个精品。
针对由于任务比较耗时而情况,传统的做法是使用多线程进行处理。将耗时的任务在单独的线程中进行处理,在任务的执行过程中,将执行的进度通过委托调用主线程的方法,将进度在界面显示给用户(在VS2005中,出于安全考虑,在线程中无法直接操作主线程上的控件,只能通知主线程,由主线程对其控件的状态进行修改)。
一、BackGroundWorker介绍
在VS2005中,为我们提供的BackGroundWorker就可以很好地为我们解决这方面的问题。即使你对多线程编程不熟悉,也可以很好地利用BackGroundWorker完成一些多线程才能完成的工作(其实BackGroundWorker在后台也是采用多线程进行工作的)。你可以把耗时的方法放在BackGroundWorker中的DoWork方法中执行,然后,通过ReportProgress方法来向主线程报告操作的进度。
二、BackGroundWorker的使用介绍
我们先来看看一个使用BackGroundWorker的DEMO,如下图:

DEMO 实现得很简单,当点“开始执行”按钮时,该软件开始执行一个耗时的动作,然后在界面显示操作的进度。我们看看Demo的代码:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1
publicpartialclassForm1:Form2

3


{4

5
publicForm1()6

7


{8

9
InitializeComponent();10

11
}12

13

14

15

/**////<summary>16

17
///模拟一个耗时的方法(让线程休眠一秒)18

19
///</summary>20

21
privatevoidGetData()22

23


{24

25
System.Threading.Thread.Sleep(1000);26

27
}28

29

30

31

/**////<summary>32

33
///开始执行按钮动作34

35
///</summary>36

37
///<paramname="sender"></param>38

39
///<paramname="e"></param>40

41
privatevoidbtn_Start_Click(objectsender,EventArgse)42

43


{44

45
if(!backgroundWorker1.IsBusy)//如果DoWork处于不忙状态,才执行该方法46

47


{48

49
//开始执行异步工作50

51
backgroundWorker1.RunWorkerAsync();52

53
}54

55
}56

57

/**////<summary>58

59
///加载的方法60

61
///</summary>62

63
///<paramname="sender"></param>64

65
///<paramname="e"></param>66

67
privatevoidForm1_Load(objectsender,EventArgse)68

69


{70

71
backgroundWorker1.WorkerReportsProgress=true;//声明异步执行的时候可以报告进度72

73

74

75
backgroundWorker1.WorkerSupportsCancellation=true;//声明可以异步取消76

77

78

79
}80

81

/**////<summary>82

83
///backgroundWorker的核心事件1,执行耗时的操作就在个方法里执行84

85
///</summary>86

87
///<paramname="sender"></param>88

89
///<paramname="e"></param>90

91
privatevoidbackgroundWorker1_DoWork(objectsender,DoWorkEventArgse)92

93


{94

95

96

97

98

99
//模拟100次的执行耗时动作100

101
for(inti=0;i<100;i++)102

103


{104

105
if(backgroundWorker1.CancellationPending)106

107


{108

109
//直接告诉程序已经执行完了,在实际的项目中,我们可以在界面显示“强行终止”110

111
backgroundWorker1.ReportProgress(0,"强行终止");112

113
break;114

115
}116

117
GetData();118

119
//向主线程报告进度(我们将i当作进度传递给主线程,当循环1次,我们就当做完成1%的工作,并报告给主线程)120

121
backgroundWorker1.ReportProgress(i,"");122

123

124

125
}126

127

128

129
}130

131

/**////<summary>132

133
///backgroundWorker的核心事件2,用于接收DoWork方法执行过程中的情况134

135
///</summary>136

137
///<paramname="sender"></param>138

139
///<paramname="e"></param>140

141
privatevoidbackgroundWorker1_ProgressChanged(objectsender,ProgressChangedEventArgse)142

143


{144

145
//接收DoWork传送过来的数据,并在界面上显示146

147
if(e.UserState.ToString()=="")148

149


{150

151
this.lbl_State.Text=e.ProgressPercentage.ToString()+"%";152

153
}154

155

else
{156

157
this.lbl_State.Text=e.UserState.ToString();158

159
}160

161

162

163
}164

165

/**////<summary>166

167
///backgroundWorker的核心事件3,当DoWork方法执行完毕时调用168

169
///</summary>170

171
///<paramname="sender"></param>172

173
///<paramname="e"></param>174

175
privatevoidbackgroundWorker1_RunWorkerCompleted(objectsender,RunWorkerCompletedEventArgse)176

177


{178

179
//DoWork执行完时自动调用该方法进行报告180

181

182

183

184

185
}186

187

/**////<summary>188

189
///取消异步执行的方法190

191
///</summary>192

193
///<paramname="sender"></param>194

195
///<paramname="e"></param>196

197
privatevoidbtn_Stop_Click(objectsender,EventArgse)198

199


{200

201
if(backgroundWorker1.IsBusy)//如果DoWork处于忙状态,才执行该方法202

203


{204

205
//开始执行异步工作206

207
backgroundWorker1.CancelAsync();208

209
}210

211
}212

213
}214
三、BackGroundWorker使用总结
方法:
backgroundWorker1.CancelAsync() 用于取消异步执行
backgroundWorker1.ReportProgress(int ,object)用于向主线层报告进度
backgroundWorker1.RunWorkerAsync():用于开始执行异步操作
属性:
backgroundWorker1.IsBusy后台是否会执行
backgroundWorker1.WorkerReportsProgress 声明异步执行时是否可以报告进度
backgroundWorker1.WorkerSupportsCancellation 声明是否可以异步取消
backgroundWorker1.CancellationPen
本文介绍了如何使用BackGroundWorker处理耗时任务,避免界面假死,提升用户体验。通过示例展示了开始执行、报告进度及取消异步操作的方法。
439

被折叠的 条评论
为什么被折叠?



