我正在研究线程安全调用,这很困难。我有一个方法可以帮助我向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;
});
}
答案 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)
});
}