日期:2014-05-18  浏览次数:21112 次

多线程中使用Invoke出现重复操作怎么解决?
有A,B,C三个窗口
A是一个初始化时候loading的窗口,B是一个注册窗口,C是主窗口
业务逻辑是程序初始化时候先显示A,然后判断是否注册分别显示B或者C。B窗口成功注册后显示C

Program.cs中的代码是
C# code

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            A a= new A();
            if (a.ShowDialog() == DialogResult.OK)
            {
                Application.Run(new C());
            }
            else
            {
                B b= new B();      
                if (b.ShowDialog() == DialogResult.OK)
                {
                    Application.Run(new C());
                }
            }



A中的代码是
C# code

delegate void RegCheckCallBack();
 public InitForm()
        {
            InitializeComponent();
            MyInit();
        }

        public void MyInit()
        {
            #region 解决“当初始化时候切换窗口会抛出 线程间操作无效 的错误”
            //Control.CheckForIllegalCrossThreadCalls = false; //最简单方法 进行非安全线程访问时,运行环境就不去检验它是否是线程安全的
            #endregion
            ThreadStart threadStart = new ThreadStart(RegCheck);//通过ThreadStart委托执行注册检测
            Thread thread = new Thread(threadStart);
            thread.Start(); 
        }

        private void RegCheck()
       {
            if (this.InvokeRequired)
            {
                RegCheckCallBack rccb = new RegCheckCallBack(RegCheck);
                this.Invoke(rccb);
            }
            else
            {
                bool chkResult = Bll.check();
                if (chkResult)
                {
                    this.DialogResult = DialogResult.OK;
                    C c = new C();
                    c.Show();
                    this.Visible = false;
                }
                else
                {
                    this.DialogResult = DialogResult.No;
                    B b = new B();
                    b.Show();
                    this.Visible = false;
                }
            }
        }



现在的问题是如果使用Invoke会弹出两个B窗口,不使用Invoke程序初始化时候如果切换窗口会提示“线程间操作无效”错误

百度过Control.CheckForIllegalCrossThreadCalls = false;这样设置可以解决,但是这种方法不好,所以想尽量使用委托解决

请问是应该修改Program还是修改A?

------解决方案--------------------
RegCheck中的B创建和你的program中的B创建好像没有任何关系吧,这样肯定就会执行两次
------解决方案--------------------
好奇怪的 Application.Run 哦!
------解决方案--------------------
如果想单纯的不弹出两个B,则给B添加了单实例检查即可。

对于添加Loading窗口,其实可以添加在主窗口的构造函数中即可,没有必要添加在Program.cs中

在构造中开线程,线程开一个最高窗口(TopMost),并显示进度即可