zoukankan
html css js c++ java
Windows 窗体多线程
Windows 窗体多线程
当我们在编写一个需要长时间运行的程序时(如数学计算,执行数据库命令,访问WebService)
常常将它们写在一个组件中,让他们在后台运行.从而不影响Windows界面的显示和界面上的交
互操作.但我们有时还是感到不怎方便,如我们不能直接应用winForm里定义的变量等.那么在
UI进程中能否直接执行长时间运行的程序,而不影响UI进程呢
?
下面的示例将解决这个问题.
本例利用多线程从长时间运行的操作(计算fbnc数列(n
>
36
))中分离出用户界面 (UI),
以将用户的后续输入传递给辅助线程(CalHandler,showDel)以调节其行为与用户界面元素
进行交互,从而实现稳定而正确的多线程处理的消息传递方案。
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Text;
using
System.Windows.Forms;
using
System.Threading;
using
System.Runtime.Remoting;
using
System.Runtime.Remoting.Messaging;
namespace
AsynchCalcPi
{
public
partial
class
Form2 : Form
{
public
Form2()
{
InitializeComponent();
Form2.calComplete
+=
new
CalHandler(Form2_calComplete);
}
void
Form2_calComplete(
string
strTemp)
{
//
为了对调用者屏蔽与此 UI 线程有关的线程安全通信信息,
//
ShowCalcResult 方法在此 UI 线程上通过 Control.BeginInvoke 方法使用 showDel 给自己发送消息。
//
Control.BeginInvoke 异步队列为 UI 线程提供服务,并且不等待结果就继续运行。
if
(
!
bClose )
this
.BeginInvoke(
new
showDel(showRes ),strTemp );
}
int
times
=
1
;
private
void
showRes(
string
strTemp)
{
times
+=
1
;
this
.richTextBox1.AppendText(
"
,
"
+
strTemp);
this
.progressBar1.Value
=
iStep
*
times
%
100
;
if
(FinishFlag)
{
//
timer1.Enabled = false;
MessageBox.Show(strTemp);
}
}
private
delegate
void
showDel(
string
stemp);
private
void
button1_Click(
object
sender, EventArgs e)
{
try
{
j
=
Int32.Parse(
this
.textBox_Num.Text.Trim());
iStep
=
100
/
j;
if
(j
<
1
)
return
;
}
catch
{
MessageBox.Show(
"
请在文本框内输入数字字符
"
);
return
;
}
for
(
int
i
=
0
; i
<
j; i
++
)
this
.richTextBox1.AppendText(
this
.ComputeFibonacci(i).ToString()
+
"
,
"
);
}
private
long
ComputeFibonacci(
int
n)
{
//
' The parameter n must be >= 0 and <= 91.
//
' Fib(n), with n > 91, overflows a long.
if
(n
<
0
||
n
>
91
)
{
MessageBox.Show(
"
value must be >= 0 and <= 91
"
,
"
n
"
);
}
long
result
=
0
;
if
(n
<
2
)
result
=
1
;
else
{
result
=
ComputeFibonacci(n
-
1
)
+
ComputeFibonacci(n
-
2
);
}
return
result;
}
public
int
AddInterlink(
int
i)
{
if
(i
<=
0
)
return
0
;
else
if
(i
>
0
&&
i
<=
2
)
return
1
;
else
return
AddInterlink(i
-
1
)
+
AddInterlink(i
-
2
);
}
private
void
button2_Click(
object
sender, EventArgs e)
{
try
{
j
=
Int32.Parse(
this
.textBox_Num.Text.Trim());
iStep
=
100
/
j;
if
(j
<
1
)
return
;
}
catch
{
MessageBox.Show(
"
请在文本框内输入数字字符
"
);
return
;
}
for
(
int
i
=
0
; i
<
j; i
++
)
this
.richTextBox1.AppendText(
this
.AddInterlink(i).ToString()
+
"
,
"
);
}
private
void
button3_Click(
object
sender, EventArgs e)
{
try
{
j
=
Int32.Parse(
this
.textBox_Num.Text.Trim());
iStep
=
100
/
j;
if
(j
<
1
)
return
;
}
catch
{
MessageBox.Show(
"
请在文本框内输入数字字符
"
);
return
;
}
ComputeFibonacciDel calcFbnc
=
new
ComputeFibonacciDel(
this
.ComputeFibonacci);
calcFbnc.BeginInvoke(j, callBack,
null
);
}
//
实时显示通知服务
private
long
ShowCalcResult(
int
n)
{
long
result1
=
0
;
for
(
int
i
=
0
; i
<
n; i
++
)
{
result1
=
this
.ComputeFibonacci(i);
//
委托calComplete 由辅助线程用于向 UI 线程回传消息,通常是有关长时间运行的操作的最新进度。
calComplete(result1.ToString() );
}
return
result1;
}
//
定义计算过程中用于传递消息的委托
public
delegate
void
CalHandler(
string
strTemp);
//
定义事件
public
static
event
CalHandler calComplete;
//
定义委托 进行异步计算Fibonacci数列
private
delegate
long
ComputeFibonacciDel(
int
n);
//
定义引用在异步操作完成时调用的回调方法.用以在计算完成后取得返回值和当前状态.
AsyncCallback callBack
=
new
AsyncCallback(ShowResult);
private
static
bool
FinishFlag
=
false
;
static
void
ShowResult(IAsyncResult ar)
{
//
Asynchronous Callback method.
//
Obtains the last parameter of the delegate call.
int
value
=
Convert.ToInt32(ar.AsyncState);
//
Obtains return value from the delegate call using EndInvoke.
AsyncResult aResult
=
(AsyncResult)ar;
ComputeFibonacciDel temp
=
(ComputeFibonacciDel)aResult.AsyncDelegate;
long
result
=
temp.EndInvoke(ar);
FinishFlag
=
true
;
calComplete(
"
当前状态代号:
"
+
value.ToString()
+
"
"
+
"
计算后的返回结果:
"
+
result.ToString());
}
int
i
=
0
;
private
void
timer1_Tick(
object
sender, EventArgs e)
{
i
+=
1
;
i
=
i
%
100
;
this
.progressBar1.Value
=
i;
}
int
j
=
0
;
int
iStep
=
1
;
ComputeFibonacciDel calcFbnc;
private
void
button4_Click(
object
sender, EventArgs e)
{
FinishFlag
=
false
;
//
停止进度条的自动滚动.让进度条根据当前进度显示
this
.timer1.Enabled
=
false
;
this
.progressBar1.Value
=
0
;
try
{
j
=
Int32.Parse(
this
.textBox_Num.Text.Trim());
iStep
=
100
/
j ;
if
(j
<
1
)
return
;
}
catch
{
MessageBox.Show(
"
请在文本框内输入数字字符
"
);
return
;
}
//
ComputeFibonacciDel,用于捆绑要传递给(从线程池中分配的)辅助线程上的ShowCalcResult 的参数。
//
当用户决定要计算 fbnc数列 时,事件处理程序将创建此委托的一个实例。
//
此工作通过调用 BeginInvoke 在线程池中进行排队。该委托实际上是由 UI 线程用于向辅助线程传递消息。
calcFbnc
=
new
ComputeFibonacciDel(
this
.ShowCalcResult );
IAsyncResult aResult
=
calcFbnc.BeginInvoke(j,callBack ,
null
);
//
已在callBack方法中写出,此处不再写此方法.
/**/
///
/Wait for the call to complete
//
aResult.AsyncWaitHandle.WaitOne();
//
long callResult = calcFbnc.EndInvoke(aResult);
}
bool
bClose
=
false
;
private
void
Form2_FormClosing(
object
sender, FormClosingEventArgs e)
{
bClose
=
true
;
}
//
参考资料:
//
http://www.microsoft.com/china/MSDN/library/archives/library/dnforms/html/winforms08162002.asp
}
}
源码:
AsynchCalcFbnc
查看全文
相关阅读:
Graceful degradation versus progressive enhancement
表现与数据分离
避免写出IE Bug
js控制元素的显示与隐藏
EntityManager方法简介
JPA EntityManager详解(一)
Springmvc中 同步/异步请求参数的传递以及数据的返回
JPA详解
单向关系中的JoinColumn
Hibernate一对多和多对一关系详解 (转载)
原文地址:https://www.cnblogs.com/furenjun/p/WinFormThreadPool.html
最新文章
noip 1995 灯的排列问题 排列组合 DFS
hdoj 4272 LianLianKan 数据太水
hdu 4277 USACO ORZ DFS
hdu5113 Black And White DFS+剪枝
Python issubclass() 函数
Python3 filter() 函数
Python bytearray() 函数
Python sum() 函数
Python3 ord() 函数
Python3 exec 函数
热门文章
Python isinstance() 函数
Python bool() 函数
Python str() 函数
Python3 open() 函数
online training
angularjs resources
color the python console text
nodejs tools
why does angular js rock
js selector libray
Copyright © 2011-2022 走看看