线程安全调用的目标UI线程控制

时间:2011-11-30 22:48:16

标签: c# winforms multithreading

我正在研究线程安全调用,这很困难。我有一个方法可以帮助我向tabcontrol添加一个新选项卡,但我想从一个与UI无关的线程中调用它。

我当前的标签创建代码如下所示。它不是线程安全的。

 TabPage tpage = new TabPage();
 tpage.BorderStyle = System.Windows.Forms.BorderStyle.None;

 //tabcontrol_borwser is the name of the tabcontrol on my ui
 tabcontrol_browser.TabPages.Insert(tabcontrol_browser.TabCount, tpage);

我如何从一个单独的线程中执行此操作,该线程允许我按主UI线程上存在的名称来定位相同的控件?

我想远离为每个控件创建线程安全的包装类,因为我必须为我创建的每个UI控件执行此操作,这是一个麻烦!

最简单的逻辑方法是创建一个如下所示的名称:

PrimaryThread.Control.tabcontrol_browser.TabPages.Insert(tabcontrol_browser.TabCount, tpage);

我有办法这样做吗?

以下是用于创建标签的整个方法:

    private String f_create_new_tab(string tab_name)
    {
        // create a new TabPage object
        tabcontrol_browser.Invoke( () => {
            TabPage tpage = new TabPage();
            tpage.BorderStyle = System.Windows.Forms.BorderStyle.None;


            //add the newly created TabPage
            //to the tabcontrol's collection of tab pages 
            tabcontrol_browser.TabPages.Insert(tabcontrol_browser.TabCount, tpage);
            int count = tabcontrol_browser.TabCount;
            tab_name = count.ToString() + ") " +tab_name;
            tpage.Text = tab_name;
            tpage.Name = tab_name;

            //create a WebBrowser object
            WebBrowser browser = new WebBrowser();
            browser.Name = "browser_" + tab_name;
            browser.Navigate("http://www.google.com");
            WaitBrowserLoading();
            //add the browser object to the tab page 
            //you created previously
            tpage.Controls.Add(browser);
            browser.Dock = DockStyle.Fill;
            tabcontrol_browser.SelectTab(tpage);

            //add some event handlers to your browser object
            browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(f_browser_pagechange);
            string browsername = "browser_" + tab_name;
            return browsername;
        });
    }

1 个答案:

答案 0 :(得分:1)

不确定这是否会对您有所帮助,但是当我尝试回调UI线程发布内容或对UI做任何事情时,我会使用此扩展方法:

   public static class ControlExtensions
   {
      public static void Invoke(this Control Control, Action Action)
      {
         Control.Invoke(Action);
      }
   }

这将是你的用法:

   if(tabcontrol_browser.InvokeRequired())
   {     
      tabcontrol.Invoke( () => {
                                 TabPage tpage = new TabPage();
                                 tpage.BorderStyle = System.Windows.Forms.BorderStyle.None;
                                 tabcontrol_browser.TabPages.Insert(tabcontrol_browser.TabCount, tpage)
                               });
   }