【问题标题】:How to display a form from another thread如何显示来自另一个线程的表单
【发布时间】:2011-07-01 15:27:39
【问题描述】:

我在我的 C# Winforms 应用程序的单独线程中运行此代码(我的表单名称是 MainForm):

DisplayDownload form2 = new DisplayDownload();

form2.TopMost = true;  
form2.Show();

但是当线程启动时,表单永远不会打开。如果我将代码移到我的应用程序的主线程上,它可以正常打开,但如果我将其作为自己的线程启动,则表单永远不会打开。

我尝试使用此帖子中接受的答案:Calling a windows form from another thread (.Net),但我收到此错误:

无法将匿名方法转换为类型“System.Delegate”,因为它不是委托类型

这是我尝试使用的代码:

MainForm.Invoke(delegate {
         DisplayDownload form2 = new DisplayDownload();


         form2.TopMost = true; 
         form2.Show();
});

谁能告诉我我做错了什么以及如何让它工作?

【问题讨论】:

  • 你应该调用BeginInvoke(),它不会等待方法完成运行。

标签: c# .net multithreading forms


【解决方案1】:

添加new MethodInvoker(delegate(),所以:

MainForm.Invoke(new MethodInvoker(delegate() 
{
             DisplayDownload form2 = new DisplayDownload();


             form2.TopMost = true; 
             form2.Show();
}));

【讨论】:

  • 当我粘贴到我的代码中时出现同样的错误:“无法将匿名方法转换为类型 'System.Delegate',因为它不是委托类型”
  • 这次我忘了添加新的MethodInvoker :)
  • 尝试使用新的更新/修订代码时出现此错误:非静态字段、方法或属性'System.Windows.Forms.Control.Invoke( System.Delegate)'
  • 我自己尝试了代码,创建了Form1Form2 并将button1 添加到Form1,当button1 单击时,我使用此代码运行Form2,一切运行正常。但是MainForm 是什么?我假设您指的是当前形式“所以在这种情况下它将被 this 关键字替换”对吗?
【解决方案2】:

您需要显式实例化委托类型:

MainForm.Invoke(new Action(delegate { ... }));

C# 2 及更高版本可以将方法组隐式转换为委托,但只能转换为特定的委托类型。
Invoke 方法采用基类 Delegate 类,因此编译器没有要创建的特定委托类型。
因此,您需要自己显式创建委托。

【讨论】:

  • 在将其添加到我的代码时出现此错误:非静态字段、方法或属性 'System.Windows.Forms.Control.Invoke(System.Delegate) 需要对象引用'。我添加了那行代码并将我的代码放在“...”的位置。对吗?
  • @fra:你需要获取MainForm类的现有实例。
【解决方案3】:

您希望哪个线程处理新表单的事件?如果您希望主线程处理事件,请按照现有示例的建议使用Control.Invoke

如果你想让新线程管理它自己的 UI 事件,那么你需要调用Application.Run。当您这样做时,表单将能够自行绘制并在屏幕上可见。

【讨论】:

  • @SLaks:在某些情况下它们是合适的,我们没有得到足够的信息来确定这是否是其中之一,所以我提出了两个选项。
【解决方案4】:
    //This is for WPF Application 
     try
       {
        Application.Current.Dispatcher.Invoke(new Action(() => { 
         DisplayDownload form2 = new DisplayDownload();
         form2.TopMost = true; 
         form2.Show();
        }));
        }
        catch(Exception ex) {
         }

      

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    相关资源
    最近更新 更多