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
Copyright © 2011-2022 走看看