从新线程调用/修改UI
本文关键字:调用 修改 UI 线程 新线程 | 更新日期: 2023-09-27 18:15:38
我想以编程方式创建一个新的线程,以编程方式创建一个浏览器选项卡,并在该浏览器选项卡内执行事件。问题是我得到一条消息说我不能在父线程的UI对象上执行UI影响。
所以我需要找到一种方法告诉新线程使用主线程的UI对象。这应该很容易做到,对吧?
下面是我目前正在使用的代码片段:
//....to this point we have told the code to run selected items in a datagrid. Each will have it's own thread.
if (row.Cells[1].Value.ToString() == "True")
{
count_active++;
//begin multithreading
Thread this_thread = new Thread(() => f_play_campaign(row.Cells[0].Value.ToString(), row.Cells[2].Value.ToString()));
this_thread.Name = "thread_" + row.Cells[0].Value.ToString();
this_thread.IsBackGround = true;
this_thread.Start();
}
}
if (count_active == 0)
{
MessageBox.Show("No campaigns are selected!");
}
}
private void f_play_campaign(string project_id, string tab_name)
{
//MessageBox.Show(tab_name);
//add new tab
string browsername = f_create_new_tab(tab_name); //this is where the code breaks!
Control browser = f_get_control_by_name(browsername);
//MessageBox.Show(browser.ToString());
//... do more code
是否有一种简单的方法来告诉线程使用主线程的UI对象?当我试图从我的方法f_create_new_tab()获得返回值时,我无法弄清楚如何使用Invoke(),而且我是如此的新,以至于我还没有弄清楚如何以与线程相同的方式使用后台工作者。
我将继续阅读关于这个问题的其他线程,但希望有人知道一个非常简单的优雅的解决方案,将满足像我这样的php程序员。
几天前我不得不处理这个问题。这很容易解决:
Thread this_thread = new Thread(() =>
this.Invoke((MethodInvoker)delegate
{
f_play_campaign(row.Cells[0].Value.ToString(), row.Cells[2].Value.ToString();
}));
基本上你需要传递给Invoke
一个MethodInvoker
的委托,它被定义为public delegate void MethodInvoker()
。
如果你想使用BackgroundWorker
,它非常相似:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) =>
{
this.Invoke((MethodInvoker) delegate { MyJobHere(); });
};
// Do the work
worker.RunWorkerAsync();
如果你想返回一些值,你可以这样做:
BackgroundWorker worker = new BackgroundWorker();
int value;
worker.DoWork += (s, e) =>
{
this.Invoke((MethodInvoker) delegate { value = DoSomething(); });
};
worker.RunWorkerAsync();
// do other processing
while (worker.IsBusy)
{
// Some other task
}
// Use the value
foo(value);
添加新方法:
private void f_play_campaign_Async(string project_id, string tab_name)
{
Action<string, string> action = f_play_campaign;
this.Invoke(action, project_id, tab_name);
}
修改线程的构造,改为调用此方法:
Thread this_thread = new Thread(() => f_play_campaign_Async(row.Cells[0].Value.ToString(), row.Cells[2].Value.ToString()));