【问题标题】:Open windows form (MDI) in thread c#在线程 c# 中打开 Windows 窗体(MDI)
【发布时间】:2016-11-16 07:34:30
【问题描述】:

我有一个 MDI 表单,现在单击 MDI 表单中的菜单,我在 PnlView(面板)中打开其他表单,这充当表单的容器。

我在想的是,当应用程序加载时,它会打开一个默认表单。 此时我想打开所有表单,但是由于一次打开所有表单会影响性能,因此其他表单打开应该在不同的线程中运行。然后如果所有表单都打开了,那么用户可以在表单之间快速切换。

   private bool IsFormAlreadyOpen(ControlItem _item)
    {
       bool reutrnValue = false;
       foreach (Control ctrl in PnlView.Controls)
       {
          if (ctrl.Name.ToLower() == _item.Control.Name.ToLower())
          {
             reutrnValue = true;
             break;
          }
       }
       return reutrnValue;
    }


This is the function which checks if form is already opened or not. So this will get all the forms open and will just bring that form to front.

Can anyone helps me with opening form in thread so that it will not impact the performance.  
I hope this makes sense.

---------------------------------------------------------------------

     private void MdiForm1_Load(object sender, EventArgs e)
    {
  OpenFirstForm(); //This ospens a default form, form name frmDefault
         bw.WorkerReportsProgress = true;
                bw.WorkerSupportsCancellation = true;
                bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
                bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                bw.RunWorkerAsync();
            }

            private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
            {
                //this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
            }

            private void bw_DoWork(object sender, DoWorkEventArgs e)
            {
                BackgroundWorker worker = sender as BackgroundWorker;

                for (int i = 1; (i <= 2); i++)
                {
                    if ((worker.CancellationPending == true))
                    {
                        e.Cancel = true;
                        break;
                    }
                    else
                    {
                        // Perform a time consuming operation and report progress.
                        //System.Threading.Thread.Sleep(500);
                       OpenForms(form1);
                       OpenForms(form2);
                        worker.ReportProgress((i * 10));
                    }
                }
            }

抛出异常,

跨线程操作无效:控件''从创建它的线程以外的线程访问

遇到异常, 没有重载 'OpenForm' 匹配委托 MethodInvoker

       this.Invoke(new MethodInvoker(OpenForm),new object[] { Keys.F12, Keys.Alt });

    private void OpenForm(Keys keyPressed, Keys modifier)
    {
---------------------------
}

【问题讨论】:

  • 对我来说听起来是个坏主意。假设您有 50 个表单,而用户只打开了其中的 10 个。多么浪费cpu和内存。还有为什么要在面板中打开 mdi 表单?
  • 未在面板中打开 MDI。面板位于 MDI 内部。在面板中打开子窗体
  • 现在假设我只需要在开始时保持打开的 5 个表单。在开始时修复 5 个表单。这样合适吗?
  • 如果有些表单打开得非常频繁,那么您可以考虑让它们保持打开状态,但前提是它们需要大量时间才能打开。否则这个没有用。同样保持它们打开意味着当用户将其拉回可见时更新内容的额外代码。
  • “在面板中打开子表单”是什么意思?

标签: c# .net multithreading winforms


【解决方案1】:

问题是您正试图从另一个线程访问在一个线程中实例化的控件。使用以下代码 sn-p 来解决您手头的问题:

// Paste this snippet in the beginning of your method
if (InvokeRequired)
{
   this.Invoke(new MethodInvoker(/*Enter the name of your method here*/));
   return;
}
// Method code goes here ......

/*
    Example:
    private void SomeMethod(object sender, EventArgs e) {
       if (InvokeRequired)
       {
         this.Invoke(new MethodInvoker(SomeMethod)); // Name of current method is 'SomeMethod'
         return;
       }
       // Code continues here
       int x,y,z;
       // Do something .....
    }
*/

希望这会有所帮助。

【讨论】:

  • @Johny Bravo 从您的代码中删除“,new object[] { Keys.F12, Keys.Alt }”部分。您不必在那里指定键。
  • this.Invoke(new MethodInvoker(OpenForm)); --还是报错,没有超载....
  • @Johny Bravo 如果这也不起作用,那么您的“OpenForm”方法有问题。
  • 如果我创建一个无参数方法,它可以工作,private void DoWork(),我可以调用它。但我原来的方法是接受两个参数。
  • @Johny Bravo 我推测您的所有方法都是事件处理程序。对于带参数的方法,您需要传递一个委托作为“MethodInvoker”的参数而不是方法名称,如下所示:delegate { (); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多