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
查看全文
相关阅读:
VM VirtualBox安装Centos6.5
桥接
程序员工作心法
策略模式-鸭子怎么飞-实例
策略模式-用什么方式去上班呢 实例
观察者模式-订报纸,语音呼叫系统实例
门面(Facade)模式--医院,保安系统实例
Promise实例的resolve方法
Promise实例的any方法
Promise实例的race方法
原文地址:https://www.cnblogs.com/furenjun/p/WinFormThreadPool.html
最新文章
python中经常用到的字符串方法
python对齐文本
python实现复制粘贴
python读取数据
Matlab-subplot_function
Matlab拟合多项式代码
python对网站的html文件进行搜寻
python从网站上下载东西
python-xlwt写入excel详解
python将数据带格式输出到excel
热门文章
湖南凤凰古城
选数 中途相遇搜索
【BZOJ2806】【CTSC2012】Cheat 广义后缀自动机+二分+Dp
【BZOJ3926】【ZJOI2015】诸神眷顾的幻想乡 广义后缀自动机
【BZOJ3675】【APIO2014】序列分割
【BZOJ1597】【Usaco2008 Mar】土地购买 斜率优化DP
【BZOJ1010】【HNOI2008】玩具装箱toy (斜率优化DP) 解题报告
win7安装 Apache2.2 PHP5.3 MySQL5.6
win64位 apache2.4 php5.4 mysql5.6
win7 VMware Workstation Centos6.5虚机桥接上网设置 详解(靠谱)
Copyright © 2011-2022 走看看