【发布时间】:2010-10-14 09:58:25
【问题描述】:
我在后台线程的静态类中,但我想创建一个新的 GUI 组件,为此我需要应用程序的主线程来执行该方法。
我该怎么做?
[注意我不认为我可以使用 InvokeRequired 作为它的静态类而不是 gui]
大卫
【问题讨论】:
我在后台线程的静态类中,但我想创建一个新的 GUI 组件,为此我需要应用程序的主线程来执行该方法。
我该怎么做?
[注意我不认为我可以使用 InvokeRequired 作为它的静态类而不是 gui]
大卫
【问题讨论】:
为了澄清这个问题,您在辅助线程上有一个静态类,您希望主线程从该类生成一个 UI 元素。
为此,您需要在静态类中设置一个事件,然后让您的 UI 监听该事件。即使它是静态的,也可以连接起来。 在您的事件句柄代码中,您可以调用主 UI 调用来实际生成 UI 元素。
class Program
{
static void Main(string[] args)
{
DoSomething.OnNeedsUI += new EventHandler<EventArgs>(DoSomething_OnNeedsUI);
Thread t = new Thread(new ThreadStart(DoSomething.Work));
t.Start();
}
private static void DoSomething_OnNeedsUI(object sender, EventArgs e)
{
Console.Write("Call Back Handled Here");
}
}
public static class DoSomething
{
public static void Work()
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(5000);
// Raise your Event so the tUI can respond
RaiseOnNeedsUI();
}
}
// Create a Customer Event that your UI will Register with
public static event EventHandler<EventArgs> OnNeedsUI;
private static void RaiseOnNeedsUI()
{
if (OnNeedsUI != null)
OnNeedsUI(null, EventArgs.Empty);
}
【讨论】:
DoSomething_OnNeedsUI 将在这里执行在工作线程中,而不是在主线程中。事件只是多播委托——它们不会神奇地跨越线程边界。
您的静态类需要对在 UI 线程上创建的某个实例类的引用,最好是控件。由于您正在创建一个控件,因此您可能已经为该控件考虑了一些表单/窗口,因此无论如何您都需要一个参考。您可以使用表单的 Invoke() 方法来编组一个调用,该调用将在 UI 线程上创建控件。
【讨论】:
您可以将 UI 控件的实例传递给该方法(然后调用该方法),或者将您想要的内容封装为委托;例如:
static void DoStuff(..., Action<string> updateMessage) {
...
//loop
updateMessage(currentState);
}
与:
DoStuff(..., msg => this.Invoke((MethodInvoker)delegate{
this.Text = msg;
}));
【讨论】: