none
怎么才能显示一个窗体,然后不阻塞当前窗体的线程呢? RRS feed

  • 问题

  • 现在有form1,form2两个窗体
    form1中有一个定时器Timer1

    我在form1中的Button1_click事件中显示form2窗体,代码如下:

    var temp=new form2();
    temp.show(this);


    在form2的load事件里面,我调用了autorestevent对象的waitone方法:

    private void form2_load()
    {
          var au=new autoresetevent(false);

          。。。。。。//进行其他操作,这部分的操作里面创建了一个线程去处理别的代码,在新建的线程处理完毕后,调用au.set()
         
          au.waitone(5000,false);

          ..........//解锁界面上的所有控件

       
    }


    现在的问题是,我想要在form1里面,当创建form2的时候,自身的定时器不会被停止,要怎么处理呢?

    2010年3月16日 8:34

答案

  • 我更新了一个示例了,并做了一个简单的解释,你看看。

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace X.WinForms.UI.Components.BackgroundWorker
    {
        public partial class D001 : Form
        {
            public D001()
            {
                InitializeComponent();
            }
    
            private void D001_Load(object sender, EventArgs e)
            {
                // 延时 3 秒显示 demo 窗体
                this.RunDelayDelegate(delegate
                {
                    // 实际上这个委托是在 UI 线程中执行的,异步只执行了 Sleep(3000) 详细看方法 RunDelayDelegate
                    DemoForm demoForm = new DemoForm();
    
                    demoForm.Load += new EventHandler(delegate(object o, EventArgs arg)
                    {
                        // 在 load 事件中向窗体 D001 添加一个控件,
                        // 因为这里使用了匿名方式所以可以直接访问窗体 D001
                        Button b = new Button();
                        b.Dock = DockStyle.Top;
                        b.Text = "你添加了一个按钮!";
    
                        this.Controls.Add(b);
                    });
    
                    demoForm.Show();
                }, 3000);
            }
    
            public delegate void ClientDelegate();
    
            public class DemoForm : Form
            {
                public DemoForm()
                {
                    this.Text = "Demo";
                }
            }
    
            #region " RunAsyncDelegate "
    
            /// <summary>
            /// 标题:BackgroundWorker 异步执行封装
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="fAsyncDelegate">用于异步执行的委托</param>
            /// <param name="fCallBackDelegate">异步执行完成后执行的加回调函数</param>
            public void RunAsyncDelegate(ClientDelegate fAsyncDelegate, ClientDelegate fCallBackDelegate)
            {
                using (System.ComponentModel.BackgroundWorker backgroundWorker = new System.ComponentModel.BackgroundWorker())
                {
                    backgroundWorker.DoWork += new DoWorkEventHandler(delegate(object o, DoWorkEventArgs workerEventArgs)
                    {
                        if (fAsyncDelegate != null)
                            fAsyncDelegate.Invoke();
                    });
    
                    backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object o, RunWorkerCompletedEventArgs e)
                    {
                        if (fCallBackDelegate != null)
                            this.BeginInvoke(fCallBackDelegate);
                    });
    
                    backgroundWorker.RunWorkerAsync();
                }
            }
    
            /// <summary>
            /// 标题:BackgroundWorker 异步执行封装
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="fAsyncDelegate">用于异步执行的委托</param>
            public void RunAsyncDelegate(ClientDelegate fAsyncDelegate)
            {
                this.RunAsyncDelegate(fAsyncDelegate, null);
            }
    
            #endregion
    
            #region " RunDelayDelegate "
    
            /// <summary>
            /// 标题:延时执行委托,这个委托是在 UI 线程中执行的。(委托在当前时间之后 N 毫秒后执行)
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="d">需要延时执行的委拖</param>
            /// <param name="fTimeSpan">延时的时间(毫秒)</param>
            public void RunDelayDelegate(ClientDelegate d, Int32 fTimeSpan)
            {
                ClientDelegate asyncDelegate = delegate
                {
                    if (fTimeSpan > 0)
                        System.Threading.Thread.Sleep(fTimeSpan);
                };
    
                this.RunAsyncDelegate(asyncDelegate, d);
            }
    
            /// <summary>
            /// 标题:延时执行委托,这个委托是在 UI 线程中执行的。(委托在当前时间之后 5 毫秒后执行)
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="d">需要延时执行的委拖</param>
            public void RunDelayDelegate(ClientDelegate d)
            {
                this.RunDelayDelegate(d, 5);
            }
    
            #endregion
        }
    }


    知识改变命运,奋斗成就人生!
    2010年3月16日 10:38
    版主

全部回复

  • 你好!

    我常使用 BackgroundWorker 控件来实现这样的需求,这里并未使用计时器这和你现在实现的方式可能不同,下面是我实现的完整示例,希望对你有帮助。

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace X.WinForms.UI.Components.BackgroundWorker
    {
        public partial class D001 : Form
        {
            public D001()
            {
                InitializeComponent();
            }
    
            private void D001_Load(object sender, EventArgs e)
            {
                // 延时 3 秒显示 demo 窗体
                this.RunDelayDelegate(delegate
                {
                    using (DemoForm demoForm = new DemoForm())
                    {
                        demoForm.ShowDialog();
                    }
                }, 3000); 
            }
    
            public delegate void ClientDelegate();
    
            public class DemoForm : Form
            {
                public DemoForm()
                {
                    this.Text = "Demo";
                }
            }
    
            #region " RunAsyncDelegate "
    
            /// <summary>
            /// 标题:BackgroundWorker 异步执行封装
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="fAsyncDelegate">用于异步执行的委托</param>
            /// <param name="fCallBackDelegate">异步执行完成后执行的加回调函数</param>
            public void RunAsyncDelegate(ClientDelegate fAsyncDelegate, ClientDelegate fCallBackDelegate)
            {
                using (System.ComponentModel.BackgroundWorker backgroundWorker = new System.ComponentModel.BackgroundWorker())
                {
                    backgroundWorker.DoWork += new DoWorkEventHandler(delegate(object o, DoWorkEventArgs workerEventArgs)
                    {
                        if (fAsyncDelegate != null)
                            fAsyncDelegate.Invoke();
                    });
    
                    backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object o, RunWorkerCompletedEventArgs e)
                    {
                        if (fCallBackDelegate != null)
                            this.BeginInvoke(fCallBackDelegate);
                    });
    
                    backgroundWorker.RunWorkerAsync();
                }
            }
    
            /// <summary>
            /// 标题:BackgroundWorker 异步执行封装
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="fAsyncDelegate">用于异步执行的委托</param>
            public void RunAsyncDelegate(ClientDelegate fAsyncDelegate)
            {
                this.RunAsyncDelegate(fAsyncDelegate, null);
            }
    
            #endregion
    
            #region " RunDelayDelegate "
    
            /// <summary>
            /// 标题:延时执行委托,这个委托是在 UI 线程中执行的。(委托在当前时间之后 N 毫秒后执行)
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="d">需要延时执行的委拖</param>
            /// <param name="fTimeSpan">延时的时间(毫秒)</param>
            public void RunDelayDelegate(ClientDelegate d, Int32 fTimeSpan)
            {
                ClientDelegate asyncDelegate = delegate
                {
                    if (fTimeSpan > 0)
                        System.Threading.Thread.Sleep(fTimeSpan);
                };
    
                this.RunAsyncDelegate(asyncDelegate, d);
            }
    
            /// <summary>
            /// 标题:延时执行委托,这个委托是在 UI 线程中执行的。(委托在当前时间之后 5 毫秒后执行)
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="d">需要延时执行的委拖</param>
            public void RunDelayDelegate(ClientDelegate d)
            {
                this.RunDelayDelegate(d, 5);
            }
    
            #endregion
        }
    }


    知识改变命运,奋斗成就人生!
    2010年3月16日 9:12
    版主
  • 我试了一下,出现一个问题,我在form2的load事件里面执行了这么一句:

    this.Invoke(new MethodInvoker(() => panel1.Parent = p));

    提示了:
    在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级。


    我需要在form2 加载完之后,把一个控件加入到form1中,这样要怎么做呢?
    2010年3月16日 10:16
  • 我更新了一个示例了,并做了一个简单的解释,你看看。

    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace X.WinForms.UI.Components.BackgroundWorker
    {
        public partial class D001 : Form
        {
            public D001()
            {
                InitializeComponent();
            }
    
            private void D001_Load(object sender, EventArgs e)
            {
                // 延时 3 秒显示 demo 窗体
                this.RunDelayDelegate(delegate
                {
                    // 实际上这个委托是在 UI 线程中执行的,异步只执行了 Sleep(3000) 详细看方法 RunDelayDelegate
                    DemoForm demoForm = new DemoForm();
    
                    demoForm.Load += new EventHandler(delegate(object o, EventArgs arg)
                    {
                        // 在 load 事件中向窗体 D001 添加一个控件,
                        // 因为这里使用了匿名方式所以可以直接访问窗体 D001
                        Button b = new Button();
                        b.Dock = DockStyle.Top;
                        b.Text = "你添加了一个按钮!";
    
                        this.Controls.Add(b);
                    });
    
                    demoForm.Show();
                }, 3000);
            }
    
            public delegate void ClientDelegate();
    
            public class DemoForm : Form
            {
                public DemoForm()
                {
                    this.Text = "Demo";
                }
            }
    
            #region " RunAsyncDelegate "
    
            /// <summary>
            /// 标题:BackgroundWorker 异步执行封装
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="fAsyncDelegate">用于异步执行的委托</param>
            /// <param name="fCallBackDelegate">异步执行完成后执行的加回调函数</param>
            public void RunAsyncDelegate(ClientDelegate fAsyncDelegate, ClientDelegate fCallBackDelegate)
            {
                using (System.ComponentModel.BackgroundWorker backgroundWorker = new System.ComponentModel.BackgroundWorker())
                {
                    backgroundWorker.DoWork += new DoWorkEventHandler(delegate(object o, DoWorkEventArgs workerEventArgs)
                    {
                        if (fAsyncDelegate != null)
                            fAsyncDelegate.Invoke();
                    });
    
                    backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object o, RunWorkerCompletedEventArgs e)
                    {
                        if (fCallBackDelegate != null)
                            this.BeginInvoke(fCallBackDelegate);
                    });
    
                    backgroundWorker.RunWorkerAsync();
                }
            }
    
            /// <summary>
            /// 标题:BackgroundWorker 异步执行封装
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="fAsyncDelegate">用于异步执行的委托</param>
            public void RunAsyncDelegate(ClientDelegate fAsyncDelegate)
            {
                this.RunAsyncDelegate(fAsyncDelegate, null);
            }
    
            #endregion
    
            #region " RunDelayDelegate "
    
            /// <summary>
            /// 标题:延时执行委托,这个委托是在 UI 线程中执行的。(委托在当前时间之后 N 毫秒后执行)
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="d">需要延时执行的委拖</param>
            /// <param name="fTimeSpan">延时的时间(毫秒)</param>
            public void RunDelayDelegate(ClientDelegate d, Int32 fTimeSpan)
            {
                ClientDelegate asyncDelegate = delegate
                {
                    if (fTimeSpan > 0)
                        System.Threading.Thread.Sleep(fTimeSpan);
                };
    
                this.RunAsyncDelegate(asyncDelegate, d);
            }
    
            /// <summary>
            /// 标题:延时执行委托,这个委托是在 UI 线程中执行的。(委托在当前时间之后 5 毫秒后执行)
            /// 作者:肖小勇
            /// 日期:2010-03-03
            /// </summary>
            /// <param name="d">需要延时执行的委拖</param>
            public void RunDelayDelegate(ClientDelegate d)
            {
                this.RunDelayDelegate(d, 5);
            }
    
            #endregion
        }
    }


    知识改变命运,奋斗成就人生!
    2010年3月16日 10:38
    版主