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
查看全文
相关阅读:
21.Merge Two Sorted Lists 、23. Merge k Sorted Lists
34. Find First and Last Position of Element in Sorted Array
leetcode 20. Valid Parentheses 、32. Longest Valid Parentheses 、301. Remove Invalid Parentheses
31. Next Permutation
17. Letter Combinations of a Phone Number
android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项
oc 异常处理
oc 类型判断
oc Delegate
oc 协议
原文地址:https://www.cnblogs.com/furenjun/p/WinFormThreadPool.html
最新文章
【转载】什么是特征工程?
The way to Go(2): 语言的主要特性与发展的环境和影响因素
The way to Go(1): Introduction
Future Works on P4
LaTex: Undefined citation warnings 解决方法
Tex: The top-level auxiliary file: *.aux I couldn't open style file IEEEtran.bst 解决方法
ovs-ofctl: s1 is not a bridge or a socket 解决方法
Ubuntu 14.04 python3.6 安装
解决 mininet gave up after 3 retries 问题
Ubuntu 14.04 下 OF-Config安装
热门文章
Ubuntu 14.04 安装libssh
OpFlex
Ubuntu 14.04 下解决maven访问速度慢问题
Ubuntu 14.04 禁用ipv6
解决Ubuntu14.04 下 E: Encountered a section with no Package: header 问题
leetcode 239. Sliding Window Maximum
leetcode 112. Path Sum 、 113. Path Sum II 、437. Path Sum III
leetcode 207. Course Schedule 、 210. Course Schedule II 、 310. Minimum Height Trees
leetcode 84. Largest Rectangle in Histogram 、85. Maximal Rectangle 、221. Maximal Square
22. Generate Parentheses
Copyright © 2011-2022 走看看