【问题标题】:WinForms App hangs after invoking a delegate from other threadWinForms 应用程序在调用其他线程的委托后挂起
【发布时间】:2013-01-16 21:34:39
【问题描述】:

我在使用带有 2 个线程的 Winforms 应用程序时遇到问题:在第二个线程中,我从 WCF 服务中提取消息。当有消息时,我需要更新 GUI:我按照How to update the GUI from another thread in C#? 此处找到的模式执行此操作。这是代码:

     private delegate void CWU(int ID); 
    public void AddNewTab(int id)
    {
        if (this.tabControl1.InvokeRequired)
        {
            CWU cb = new CWU(AddNewTab);
            this.tabControl1.Invoke(cb,id);
        }
        else
        {
            User ToChatWith = ContactsHelper.AllFriends.Find(e => e.ID == id);
            tabpage.Text = ToChatWith.ToString();
            this.tabControl1.TabPages.Add(tabpage);
            this.tabControl1.SelectTab(tabpage);
        }

选项卡已正确添加,当我们离开此方法时,应用程序没有响应,调试中没有信息。添加此选项卡后运行我的应用程序时,我得到 AppHangB1 没有任何详细信息。你能帮帮我吗?

【问题讨论】:

  • AddRTB 是做什么的?您是说 AddNewTab 吗?
  • 这是一个旧代码,它是 CWU cb = new CWU(AddNewTab); ,对不起
  • 您多久从另一个线程调用 AddNewTab?考虑激活异常(菜单 Debug/Exceptions)并查看是否抛出任何异常。
  • 只有在没有标签的用户有新消息时。在我的测试中,每次运行只调用一次。
  • tabpage 是在哪里创建的?可以多次添加吗?另外,假设需要一些时间来处理,在工作线程而不是 GUI 线程中创建 ToChatWith 不是更好吗?

标签: c# winforms multithreading


【解决方案1】:

试试这个:

if (this.InvokeRequired)
{
    this.Invoke((MethodInvoker)delegate
    {
        AddNewTab(id);
    });
}

【讨论】:

  • 与您的代码 @Alex 和 ' if (this.tabControl1.InvokeRequired) { this.tabControl1.Invoke((MethodInvoker)delegate { AddNewTab(id); }); 相同}'
【解决方案2】:

如果被调用线程忙于做某事,Invoke 可能会挂起。 (如果 BeginInvoke 调用而不是您的 Invoke 不会挂起,您可能会知道这种情况。Invoke 会阻塞直到调用成功,BeginInvoke 不会。)

【讨论】:

    【解决方案3】:

    用这个替换你的方法:

        private void dbg(string s)
        {
            System.Diagnostics.Debug.WriteLine("AddNewTab({0}): {1}", 
                Thread.CurrentThread.ManagedThreadId, s);
        }
        public void AddNewTab(int id)
        {
            try
            {
                dbg("entered");
                if (this.tabControl1.InvokeRequired)
                {
                    new Thread(delegate() { try {
                            CWU cb = new CWU(AddNewTab);
                            dbg("calling Invoke");
                            this.tabControl1.Invoke(cb, id);
                            dbg("Invoke returned");
                        } catch (Exception ex) { dbg("" + ex); }
                    }).Start();
                    dbg("created sub-thread");
                }
                else
                {
                    dbg("setting tabpage.Text");
                    User ToChatWith = ContactsHelper.AllFriends
                        .Find(e => e.ID == id);
                    tabpage.Text = ToChatWith.ToString();
                    dbg("adding tab");
                    this.tabControl1.TabPages.Add(tabpage);
                    this.tabControl1.SelectTab(tabpage);
                    dbg("done adding tab");
                }
                dbg("leaving");
            }
            catch (Exception ex)
            {
                dbg("" + ex);
            }
        }
    

    确保您可以在您的环境中找到调试器输出。 (见鬼,如果有帮助,请使用 Console.WriteLine)

    如果这不能帮助您诊断问题,我不知道会怎样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-09
      • 2013-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多