Windows 窗体构建在第二个线程中失败

Posted

技术标签:

【中文标题】Windows 窗体构建在第二个线程中失败【英文标题】:Windows Form building failed in second thread 【发布时间】:2014-07-23 21:37:55 【问题描述】:

首先是我的问题:

我尝试在后台工作人员中构建一个 winform。这个 Form 类只包含一个 webbrowser 控件。表单不会构建并跳出到主线程。 我在带有 WinForms 的 Visual Studio 2013 Pro 上使用带有 .NET 4.5 的 c#

我做什么:

启动后台工作者

    private void bt_dashboard_chat_Click(object sender, EventArgs e)
    
        if (!this.bw_webchat.IsBusy)
        
            this.bw_webchat.RunWorkerAsync(this.auth.getUserName());
        
    

工人

      
        String name = e.Argument as String;
        DashBoard.Forms.Chat.DummyChat tmp = new Forms.Chat.DummyChat(name);
        tmp.ShowDialog();
      

表单构造函数

        InitializeComponent();
        this.wb_twitchchat.Url = new Uri("http://link.tld/" + name + "/chat");
        this.Text = "Chat of " + name;

问题。线程在 InitializeComponent() 处跳出;就行了

this.wb_twitchchat = new System.Windows.Forms.WebBrowser();

这是第二行。

有人知道为什么会这样吗?其他形式在后台工作线程中工作正常:/

【问题讨论】:

我的意思是在这一行之后 (this.wb_twitchchat = new System.Windows.Forms.WebBrowser();) 其余部分被跳过,没有发生任何事情,我又回到了主线程中。 那么它很可能会抛出异常。您是否检查了“输出”窗口中是否存在异常,可能没有中断执行? 忘记检查输出:/ Output:"System.Threading.ThreadStateException" in System.Windows.Forms.dll" 有什么想法吗?^^ 我用 try catch 捕获了异常,我得到以下消息:“Das ActiveX-Steuerelement 8856f961-340a-11d0-a96b-00c04fd705a2 kann nicht instanziiert werden, da der aktuelle Thread kein Singlethread-Apartment ist 。”很抱歉德国异常消息,不知道如何更改它。 Ok 找到了解决方案:后台工作人员不支持 ApartmentState.STA 所以我需要使用 SetApartmentState(ApartmentState.STA); 切换到普通线程;现在它工作正常。问题是 Webbrowser 控件需要 ApartmentState.STA。 【参考方案1】:

异常被后台工作者自己捕获。在您提到“工人”的代码周围使用 try/catch 块。

捕获的异常应该是这样的: ActiveX 控件“8856f961-340a-11d0-a96b-00c04fd705a2”无法实例化,因为当前线程不在单线程单元中。

异常基于代码:

    private void button1_Click(object sender, EventArgs e)
    
        var bw = new BackgroundWorker();
        bw.DoWork += BwOnDoWork;
        bw.RunWorkerAsync();

    

    private void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
    
        try
        
            WebBrowser wb = new WebBrowser();
        
        catch (Exception ex)
        
        
    

【讨论】:

感谢回复。是的,你说的没错。使用 Thread 寻找解决方案。删除整个后台工作人员并使用 SetApartmentState(ApartmentState.STA) 添加一个新线程。现在工作正常:)

以上是关于Windows 窗体构建在第二个线程中失败的主要内容,如果未能解决你的问题,请参考以下文章

c#中让Windows窗体只运行一次,并在第二次启动窗体时激活该窗体

在第二个线程中显示图像,OpenCV?

c++ 当在一个线程中写入并在第二个线程中读取同一个对象时会发生啥? (它安全吗?)[重复]

跨窗体操作

我正在尝试在第二个线程中向自身添加一个 int 并且我的主线程中没有任何变化

wpf我在第一个窗体后新建了一个窗体,要怎么弄才能使程序运行时先显示我新建的那个窗体?