Windows 窗体多线程

 

None.gif                        Windows 窗体多线程
None.gif    当我们在编写一个需要长时间运行的程序时(如数学计算,执行数据库命令,访问WebService)
None.gif常常将它们写在一个组件中,让他们在后台运行.从而不影响Windows界面的显示和界面上的交
None.gif互操作.但我们有时还是感到不怎方便,如我们不能直接应用winForm里定义的变量等.那么在
None.gifUI进程中能否直接执行长时间运行的程序,而不影响UI进程呢
?
None.gif    下面的示例将解决这个问题.
None.gif    本例利用多线程从长时间运行的操作(计算fbnc数列(n
> 36 ))中分离出用户界面 (UI),
None.gif以将用户的后续输入传递给辅助线程(CalHandler,showDel)以调节其行为与用户界面元素
None.gif进行交互,从而实现稳定而正确的多线程处理的消息传递方案。 

None.gif
None.gif
using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.ComponentModel;
None.gif
using  System.Data;
None.gif
using  System.Drawing;
None.gif
using  System.Text;
None.gif
using  System.Windows.Forms;
None.gif
using  System.Threading;
None.gif
using  System.Runtime.Remoting;
None.gif
using  System.Runtime.Remoting.Messaging;
None.gif
None.gif
None.gif
namespace  AsynchCalcPi
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public partial class Form2 : Form
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public Form2()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            InitializeComponent();
InBlock.gif            Form2.calComplete 
+= new CalHandler(Form2_calComplete);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
void Form2_calComplete(string strTemp)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            
//为了对调用者屏蔽与此 UI 线程有关的线程安全通信信息, 
InBlock.gif            
//ShowCalcResult 方法在此 UI 线程上通过 Control.BeginInvoke 方法使用 showDel 给自己发送消息。
InBlock.gif            
//Control.BeginInvoke 异步队列为 UI 线程提供服务,并且不等待结果就继续运行。
InBlock.gif
            if(!bClose )
InBlock.gif            
this.BeginInvoke(new showDel(showRes ),strTemp );
InBlock.gif          
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
int times = 1;
InBlock.gif        
private void showRes(string strTemp)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            times 
+= 1;
InBlock.gif            
this.richTextBox1.AppendText("," + strTemp); 
InBlock.gif            
this.progressBar1.Value = iStep * times%100
InBlock.gif            
if (FinishFlag)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif               
InBlock.gif                
//timer1.Enabled = false;
InBlock.gif
                MessageBox.Show(strTemp);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
private delegate void showDel(string stemp);
InBlock.gif
InBlock.gif
InBlock.gif
InBlock.gif        
private void button1_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                j 
= Int32.Parse(this.textBox_Num.Text.Trim());
InBlock.gif                iStep 
= 100 / j;
InBlock.gif                
if (j < 1)
InBlock.gif                    
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"请在文本框内输入数字字符");
InBlock.gif                
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
for (int i = 0; i < j; i++)
InBlock.gif                
this.richTextBox1.AppendText(this.ComputeFibonacci(i).ToString() + ",");
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif
InBlock.gif        
private long ComputeFibonacci(int n)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//' The parameter n must be >= 0 and <= 91.
InBlock.gif            
//' Fib(n), with n > 91, overflows a long.
InBlock.gif
            if (n < 0 || n > 91)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"value must be >= 0 and <= 91""n");
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
long result = 0;
InBlock.gif
InBlock.gif            
if (n < 2)
InBlock.gif                result 
= 1;
InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                result 
= ComputeFibonacci(n - 1+ ComputeFibonacci(n - 2);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return result;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public int AddInterlink(int i)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (i <= 0)
InBlock.gif                
return 0;
InBlock.gif            
else if (i > 0 && i <= 2)
InBlock.gif                
return 1;
InBlock.gif            
else return AddInterlink(i - 1+ AddInterlink(i - 2);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void button2_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                j 
= Int32.Parse(this.textBox_Num.Text.Trim());
InBlock.gif                iStep 
= 100 / j;
InBlock.gif                
if (j < 1)
InBlock.gif                    
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"请在文本框内输入数字字符");
InBlock.gif                
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
for (int i = 0; i < j; i++)
InBlock.gif                
this.richTextBox1.AppendText(this.AddInterlink(i).ToString() + ",");
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private void button3_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                j 
= Int32.Parse(this.textBox_Num.Text.Trim());
InBlock.gif                iStep 
= 100 / j;
InBlock.gif                
if (j < 1)
InBlock.gif                    
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"请在文本框内输入数字字符");
InBlock.gif                
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif            ComputeFibonacciDel calcFbnc 
= new ComputeFibonacciDel(this.ComputeFibonacci);
InBlock.gif
InBlock.gif            calcFbnc.BeginInvoke(j, callBack, 
null);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
//实时显示通知服务
InBlock.gif
        private long ShowCalcResult(int n)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
long result1 = 0;
InBlock.gif            
for (int i = 0; i < n; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                result1 
= this.ComputeFibonacci(i);
InBlock.gif                
//委托calComplete 由辅助线程用于向 UI 线程回传消息,通常是有关长时间运行的操作的最新进度。
InBlock.gif
              
InBlock.gif                calComplete(result1.ToString() ); 
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return result1;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
//定义计算过程中用于传递消息的委托
InBlock.gif
        public delegate void CalHandler(string strTemp);
InBlock.gif        
//定义事件
InBlock.gif
        public static event CalHandler calComplete;
InBlock.gif        
//定义委托 进行异步计算Fibonacci数列
InBlock.gif
        private delegate long ComputeFibonacciDel(int n); 
InBlock.gif
InBlock.gif        
//定义引用在异步操作完成时调用的回调方法.用以在计算完成后取得返回值和当前状态.
InBlock.gif
        AsyncCallback callBack = new AsyncCallback(ShowResult);
InBlock.gif        
private  static  bool  FinishFlag = false;
InBlock.gif        
static void ShowResult(IAsyncResult ar)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
// Asynchronous Callback method.
InBlock.gif            
// Obtains the last parameter of the delegate call.
InBlock.gif
            int value = Convert.ToInt32(ar.AsyncState);
InBlock.gif            
// Obtains return value from the delegate call using EndInvoke.
InBlock.gif
            AsyncResult aResult = (AsyncResult)ar;
InBlock.gif            ComputeFibonacciDel temp 
= (ComputeFibonacciDel)aResult.AsyncDelegate;
InBlock.gif            
long result = temp.EndInvoke(ar);
InBlock.gif            FinishFlag 
= true;
InBlock.gif
InBlock.gif            calComplete(
"当前状态代号:" + value.ToString() + "  " + "计算后的返回结果:" + result.ToString());
InBlock.gif           
ExpandedSubBlockEnd.gif        }

InBlock.gif        
int i = 0;
InBlock.gif        
private void timer1_Tick(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            i 
+= 1;
InBlock.gif            i 
= i % 100;
InBlock.gif            
this.progressBar1.Value = i;
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
int j = 0;
InBlock.gif        
int iStep = 1;
InBlock.gif        ComputeFibonacciDel calcFbnc;
InBlock.gif        
private void button4_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            FinishFlag 
= false;
InBlock.gif            
//停止进度条的自动滚动.让进度条根据当前进度显示
InBlock.gif
            this.timer1.Enabled = false;
InBlock.gif            
this.progressBar1.Value = 0
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif               j
= Int32.Parse(this.textBox_Num.Text.Trim());
InBlock.gif               iStep 
= 100 / j ;
InBlock.gif                
if (j < 1)
InBlock.gif                    
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MessageBox.Show(
"请在文本框内输入数字字符");
InBlock.gif                
return;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
//ComputeFibonacciDel,用于捆绑要传递给(从线程池中分配的)辅助线程上的ShowCalcResult 的参数。
InBlock.gif            
//当用户决定要计算 fbnc数列 时,事件处理程序将创建此委托的一个实例。
InBlock.gif            
//此工作通过调用 BeginInvoke 在线程池中进行排队。该委托实际上是由 UI 线程用于向辅助线程传递消息。
InBlock.gif
           calcFbnc = new ComputeFibonacciDel(this.ShowCalcResult );
InBlock.gif
InBlock.gif            IAsyncResult aResult
= calcFbnc.BeginInvoke(j,callBack , null);
InBlock.gif           
InBlock.gif            
//已在callBack方法中写出,此处不再写此方法.
ExpandedSubBlockStart.gifContractedSubBlock.gif
            /**/////Wait for the call to complete
InBlock.gif            //aResult.AsyncWaitHandle.WaitOne();
InBlock.gif            
//long callResult = calcFbnc.EndInvoke(aResult);
ExpandedSubBlockEnd.gif
        }

InBlock.gif        
bool bClose = false;
InBlock.gif        
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            bClose 
= true;
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif     
InBlock.gif
InBlock.gif        
//参考资料:
InBlock.gif        
//http://www.microsoft.com/china/MSDN/library/archives/library/dnforms/html/winforms08162002.asp
InBlock.gif

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
源码: AsynchCalcFbnc
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值