C#多线程调用窗体闪退

谷凯Jump 2019-10-14 04:40:41
代码如下,我在Form1通过Thread调用Form2窗体时,Form2打开后就立马关闭了,请问如何处理?

感谢。

至于为什么使用多线程,因为需要查库判断是否要显示Form2,不想Form1假死。


private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 5000;
timer1.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
System.Threading.Thread thread = new System.Threading.Thread(ShowForm2);
thread.Start();
}

private void ShowForm2()
{
//根据一系列代码查询条件,判断是否要执行以下弹窗


Form2 form = new Form2();//将窗口Messages 实例化
Point p = new Point(Screen.PrimaryScreen.WorkingArea.Width - form.Width, Screen.PrimaryScreen.WorkingArea.Height);
form.PointToClient(p);
form.Location = p;
form.Show();
for (int i = 0; i < form.Height; i++)
{
form.Location = new Point(p.X, p.Y - i);
System.Threading.Thread.Sleep(1);//消息框弹出速度,数值越大越慢
}
}
...全文
1959 41 打赏 收藏 转发到动态 举报
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
强军计划 2019-10-21
  • 打赏
  • 举报
回复
在最后面加一个 system(“pause”)
jlennonxzy 2019-10-19
  • 打赏
  • 举报
回复
引用 21 楼 胖叔叔写代码 的回复:
1、哪个窗体的ui修改,请放置在哪个窗体,用窗体间交互的方法处理数据传递。 2、非窗体主线程操作ui请使用Invoke操作ui,根据实际情况也可以使用endInvoke或者beginInvoke。 3、事实上窗体程序也是多线程的,基本线程也就是窗体主线程请不要随意阻塞,否则导致的问题你可能处理不过来。
学习到了,谢谢.
donaldshp 2019-10-18
  • 打赏
  • 举报
回复
我正想学习下
谷凯Jump 2019-10-18
  • 打赏
  • 举报
回复
引用 40 楼 莫南小茂 的回复:
[quote=引用 39 楼 莫南小茂 的回复:]

        private void ShowForm2()
        {
            //根据一系列代码查询条件,判断是否要执行以下弹窗

            Application.Run(new Form2());

            //Form2 form = new Form2();//将窗口Messages 实例化
            //Point p = new Point(Screen.PrimaryScreen.WorkingArea.Width - form.Width, Screen.PrimaryScreen.WorkingArea.Height);
            //form.PointToClient(p);
            //form.Location = p;
            //form.Show();
            //for (int i = 0; i < form.Height; i++)
            //{
            //    form.Location = new Point(p.X, p.Y - i);
            //    System.Threading.Thread.Sleep(1);//消息框弹出速度,数值越大越慢
            //}
        }
Invoke也是一种方法,但我猜你想要的是这个。 具体什么意思请查看Application.Run的方法的含义[/quote] 这个会报错呢~
mnxm 2019-10-18
  • 打赏
  • 举报
回复
引用 39 楼 莫南小茂 的回复:

        private void ShowForm2()
        {
            //根据一系列代码查询条件,判断是否要执行以下弹窗

            Application.Run(new Form2());

            //Form2 form = new Form2();//将窗口Messages 实例化
            //Point p = new Point(Screen.PrimaryScreen.WorkingArea.Width - form.Width, Screen.PrimaryScreen.WorkingArea.Height);
            //form.PointToClient(p);
            //form.Location = p;
            //form.Show();
            //for (int i = 0; i < form.Height; i++)
            //{
            //    form.Location = new Point(p.X, p.Y - i);
            //    System.Threading.Thread.Sleep(1);//消息框弹出速度,数值越大越慢
            //}
        }
Invoke也是一种方法,但我猜你想要的是这个。 具体什么意思请查看Application.Run的方法的含义
mnxm 2019-10-18
  • 打赏
  • 举报
回复

        private void ShowForm2()
        {
            //根据一系列代码查询条件,判断是否要执行以下弹窗

            Application.Run(new Form2());

            //Form2 form = new Form2();//将窗口Messages 实例化
            //Point p = new Point(Screen.PrimaryScreen.WorkingArea.Width - form.Width, Screen.PrimaryScreen.WorkingArea.Height);
            //form.PointToClient(p);
            //form.Location = p;
            //form.Show();
            //for (int i = 0; i < form.Height; i++)
            //{
            //    form.Location = new Point(p.X, p.Y - i);
            //    System.Threading.Thread.Sleep(1);//消息框弹出速度,数值越大越慢
            //}
        }
  • 打赏
  • 举报
回复
不小得不晓得不晓得还是不晓得
星兵山 2019-10-17
  • 打赏
  • 举报
回复
WinForm不可以跨线程调用窗体控件的,要invoke一下才行 WPF也不可以哦
qq_33204306 2019-10-17
  • 打赏
  • 举报
回复
采用定时试试
xiaoxiangqing 2019-10-16
  • 打赏
  • 举报
回复
21楼的有道理
  • 打赏
  • 举报
回复
把查询数据库部分放到多线程里就行了,打开窗口操作没必须要也放到里边。
wendyone 2019-10-15
  • 打赏
  • 举报
回复
UI一定要用UI主线程,查询数据库可以用新线程,用invoke回调UI线程。
燃烧的荷尔蒙 2019-10-15
  • 打赏
  • 举报
回复
引用 26 楼 谷凯Jump 的回复:
以下是我最终的设计方法,我这边是实现效果了,请各位帮忙看下是否有什么不妥呢?
        private void MainForm_Load(object sender, EventArgs e)
        {
            timer1.Start(); //用于读库判断是否要显示新的窗体
            timer2.Start(); //用于显示新的窗体
        }

        bool blnShowForm2 = false;  //在timer1中读库后修改该变量,在timer2中读取该变量

        private void timer1_Tick(object sender, EventArgs e)
        {
            //后台运行timer1
            System.Threading.ThreadStart start = new System.Threading.ThreadStart(this.CheckToShow);
            new System.Threading.Thread(start).Start();
        }
         
        private void CheckToShow()
        {
            //模拟查库判断逻辑
            int a = 5;
            int b = 3;
            if ( a > b )
            {
                blnShowForm2 = true;
            }
            else
            {
                blnShowForm2 = false;
            }
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            if (blnShowForm2)
            {
                ShowForm2();
            }
        }

        private void ShowForm2()
        {
            //根据timer1的判断结果决定是否执行以下步骤
            if (!blnShowForm2)
            {
                return;
            }
            Form2 form = new Form2();//将窗口Messages 实例化
            Point p = new Point(Screen.PrimaryScreen.WorkingArea.Width - form.Width, Screen.PrimaryScreen.WorkingArea.Height);
            form.PointToClient(p);
            form.Location = p;
            form.Show();
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                for (int i = 0; i < form.Height; i++)
                {
                    this.Invoke((MethodInvoker)delegate
                    {
                        form.Location = new Point(p.X, p.Y - i);
                    });
                    System.Threading.Thread.Sleep(1);//消息框弹出速度,数值越大越慢
                }
            });
        }
我觉得还算OK啊,但是弹出后记得blnShowForm2 = false;
谷凯Jump 2019-10-15
  • 打赏
  • 举报
回复
以下是我最终的设计方法,我这边是实现效果了,请各位帮忙看下是否有什么不妥呢?
        private void MainForm_Load(object sender, EventArgs e)
        {
            timer1.Start(); //用于读库判断是否要显示新的窗体
            timer2.Start(); //用于显示新的窗体
        }

        bool blnShowForm2 = false;  //在timer1中读库后修改该变量,在timer2中读取该变量

        private void timer1_Tick(object sender, EventArgs e)
        {
            //后台运行timer1
            System.Threading.ThreadStart start = new System.Threading.ThreadStart(this.CheckToShow);
            new System.Threading.Thread(start).Start();
        }
         
        private void CheckToShow()
        {
            //模拟查库判断逻辑
            int a = 5;
            int b = 3;
            if ( a > b )
            {
                blnShowForm2 = true;
            }
            else
            {
                blnShowForm2 = false;
            }
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            if (blnShowForm2)
            {
                ShowForm2();
            }
        }

        private void ShowForm2()
        {
            //根据timer1的判断结果决定是否执行以下步骤
            if (!blnShowForm2)
            {
                return;
            }
            Form2 form = new Form2();//将窗口Messages 实例化
            Point p = new Point(Screen.PrimaryScreen.WorkingArea.Width - form.Width, Screen.PrimaryScreen.WorkingArea.Height);
            form.PointToClient(p);
            form.Location = p;
            form.Show();
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                for (int i = 0; i < form.Height; i++)
                {
                    this.Invoke((MethodInvoker)delegate
                    {
                        form.Location = new Point(p.X, p.Y - i);
                    });
                    System.Threading.Thread.Sleep(1);//消息框弹出速度,数值越大越慢
                }
            });
        }
谷凯Jump 2019-10-15
  • 打赏
  • 举报
回复
引用 21 楼 胖叔叔写代码 的回复:
1、哪个窗体的ui修改,请放置在哪个窗体,用窗体间交互的方法处理数据传递。 2、非窗体主线程操作ui请使用Invoke操作ui,根据实际情况也可以使用endInvoke或者beginInvoke。 3、事实上窗体程序也是多线程的,基本线程也就是窗体主线程请不要随意阻塞,否则导致的问题你可能处理不过来。
感谢你的思路~
谷凯Jump 2019-10-15
  • 打赏
  • 举报
回复
引用 23 楼 燃烧的荷尔蒙 的回复:
我觉得这个设计不太好,用户不点窗体就一直弹吗?用户一段时间不在,弹了十几上百个窗体在那,会占用很大内存的!
不是一直弹哦,是有一条消息就弹一次
燃烧的荷尔蒙 2019-10-15
  • 打赏
  • 举报
回复
我觉得这个设计不太好,用户不点窗体就一直弹吗?用户一段时间不在,弹了十几上百个窗体在那,会占用很大内存的!
燃烧的荷尔蒙 2019-10-15
  • 打赏
  • 举报
回复
别说那么多了,代码来得直接点!

        private void ShowForm2()
        {
            //根据一系列代码查询条件,判断是否要执行以下弹窗


            this.Invoke(new EventHandler(delegate
            {
                Form2 form = new Form2();//将窗口Messages 实例化
                Point p = new Point(Screen.PrimaryScreen.WorkingArea.Width - form.Width, Screen.PrimaryScreen.WorkingArea.Height);
                form.PointToClient(p);
                form.Location = p;
                form.Show();
                for (int i = 0; i < form.Height; i++)
                {
                    form.Location = new Point(p.X, p.Y - i);
                    System.Threading.Thread.Sleep(5);//消息框弹出速度,数值越大越慢
                }

            }));
        }
  • 打赏
  • 举报
回复
1、哪个窗体的ui修改,请放置在哪个窗体,用窗体间交互的方法处理数据传递。 2、非窗体主线程操作ui请使用Invoke操作ui,根据实际情况也可以使用endInvoke或者beginInvoke。 3、事实上窗体程序也是多线程的,基本线程也就是窗体主线程请不要随意阻塞,否则导致的问题你可能处理不过来。
大鱼> 2019-10-15
  • 打赏
  • 举报
回复
窗体是基于UI线程的,你新开的线程里面如果用到对窗体的操作需要通过委托处理。 用this.Invoke()来操作界面
加载更多回复(21)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧