首页 新闻 会员 周边

c# winform 多线程高手进

0
悬赏园豆:10 [已解决问题] 解决于 2013-05-06 22:27

代码段1:打开后直接闪了一下就没了!!为什么

 public partial class Form1 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        private Thread tr;
        private void button1_Click(object sender, EventArgs e)
        {
            tr = new Thread(new ThreadStart(Do));
            tr.IsBackground = false;
            tr.Start();
        }
        private void Do()
        {
            Form3 f = new Form3();
            f.Show();
        }
    }

 

 

代码段2:只能打开一个save ???请问是怎么回事??

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 f = new Form2();
            f.Show();
            Form2 f1 = new Form2();
            f1.Show();
        }
    }

 

public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            this.FormClosing += new FormClosingEventHandler(Form2_FormClosing);
            Thread td = new Thread(DO);
            td.Name = "from2";
            td.Start();
        }

        private void DO()
        {
            Thread.Sleep(2000);
            this.Invoke(new Action(() =>
            {
                this.Close();
            }));
        }

        void Form2_FormClosing(object sender, FormClosingEventArgs e)
        {
            System.Windows.Forms.SaveFileDialog sd = new SaveFileDialog();
            sd.ShowDialog();
        }
    }

KeVinDurant的主页 KeVinDurant | 初学一级 | 园豆:5
提问于:2013-03-28 20:57
< >
分享
最佳答案
0

试了下第一种,弹出两个,关掉一个不会一起关掉另一个啊……

第二种应该是一个保存框关掉才会出现第二个吧

收获园豆:10
滴答的雨 | 老鸟四级 |园豆:3660 | 2013-03-28 22:10

第一种是我写错代码了。。第二种你肯定没有试过!!

KeVinDurant | 园豆:5 (初学一级) | 2013-03-28 22:53

@KeVinDurant: 

第一段代码

因为辅助线程运行完tr = new Thread(new ThreadStart(Do));的Do方法后就stop掉了,所以线程创建的对象也被释放掉。。。为什么辅助线程会释放,而主窗体的线程能等待消息呢。因为Application.Run()运行内部调用了RunMessageLoop,启动了线程消息循环机制 ,所以主线程会等待消息进行下一步操作

 

第二段代码,确实是关掉一个才会出另一个,并且这边多线程ShowDialog()显示模态窗体会导致Windows机制错误吧,弹出的保存框会有一点异常。(因为模态窗体就是阻止别的窗体获得消息,但是你这边一下弄了两个模态窗体)

 

另外,测试中还发现在窗体一次窗体关闭时会触发两次closing,估计是在此事件中抛出模态窗体引起的……

滴答的雨 | 园豆:3660 (老鸟四级) | 2013-03-29 00:16

@滴答的雨: 第二个问题的:是弹出一个save后。。我关闭了。这个save。。这时候 f f1两个form同时关闭!!!

而且是试了一下。如果改成这样!两个save都出不来了。

        public Form2()
        {
            InitializeComponent();
            this.FormClosing += new FormClosingEventHandler(Form2_FormClosing);
            Thread td = new Thread(DO);
            td.Name = "from2";
            td.Start();
        }

        private void DO()
        {
            System.Windows.Forms.SaveFileDialog sd = new SaveFileDialog();
            sd.ShowDialog();
        }

KeVinDurant | 园豆:5 (初学一级) | 2013-03-30 13:01

@滴答的雨: 改成这样。。一切正常。两个都能弹出!!能解释下为什么吗

    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            this.FormClosing += new FormClosingEventHandler(Form2_FormClosing);
            Thread td = new Thread(DO);
            td.SetApartmentState(ApartmentState.STA);
            td.Name = "from2";
            td.Start();
        }

        private void DO()
        {
            System.Windows.Forms.SaveFileDialog sd = new SaveFileDialog();
            sd.ShowDialog();
        }

KeVinDurant | 园豆:5 (初学一级) | 2013-03-30 13:26

@KeVinDurant: 

改成这样。。一切正常。两个都能弹出!!能解释下为什么吗?

最开始的第二段代码:为什么会一个一个showDialog,是因为消息都是在主线程上传递的(Form2_FormClosing),有顺序,所以一个一个来。。你后面改在Do()里面是用两个辅助线程去做,两个队列并行执行

 

没有td.SetApartmentState(ApartmentState.STA);这段代码,报ole调用需要STA线程,这个问题我之前回复过你,就不需要copy了吧,那么大一段copy过来你也不一定会看!

 

滴答的雨 | 园豆:3660 (老鸟四级) | 2013-03-30 15:01

@滴答的雨: 代码段2  是根本不会一个个showDialog呀。!只是showDialog了一个。。我点了取消。。两个form(f,f1)同时关闭了!你可以贴代码过去运行看看!

KeVinDurant | 园豆:5 (初学一级) | 2013-03-30 22:11

@KeVinDurant: 试过了,我本地一个一个showdialog()。。。环境:win8 .net3.0+.net4.0+.net4.5

滴答的雨 | 园豆:3660 (老鸟四级) | 2013-03-30 23:28

@滴答的雨: 不可能啦兄弟。。你可以全部拷过去。。打开f,f1的时候你别手动去选中他们。双击了按钮后等着弹开一个save。。然后点取消。。。你会发现两个form都关闭了。!!!

KeVinDurant | 园豆:5 (初学一级) | 2013-03-31 17:17
其他回答(2)
0

第一个问题不提。

第二个模态对话框在多线程中要指定对话框的所有者,你的代码中会同时关闭两个对话框,改成:sd.ShowDialog(this); 试试

S-Lyy | 园豆:257 (菜鸟二级) | 2013-03-29 11:00
0

你好。  你这个情况是 这样子的。 直接给你代码吧。

private void button1_Click(object sender, EventArgs e)
{
Form2 f = new Form2("name1");
f.Show();
Form2 f1 = new Form2("name2");
f1.Show();
}

 

这个是Form1的。

public Form2(string name)
{
InitializeComponent();
this.FormClosing += new FormClosingEventHandler(Form2_FormClosing);
Thread td = new Thread(DO);
td.SetApartmentState(ApartmentState.STA);
td.Name = name;
td.Start();
}

 

这个是Form2的构造函数。

Form2在this.close()的时候这个函数是由 子线程调用的, 一旦这个子线程调用结束 就是abort 这个线程。  之前你的代码 使得 每个实例里新建的线程都是一个名字,  这样就都abort的。 当然你点了一次取消  2个就都关闭了

kotl | 园豆:5 (初学一级) | 2013-04-03 17:01
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册