我在一个后台线程中的静态类,但我想创建一个新的GUI组件,要做到这一点,我需要执行该方法的应用程序的主线程。c#回调主线程
我该怎么做?
[注意我不认为我可以使用InvokeRequired作为它的一个静态类不是GUI]
大卫
我在一个后台线程中的静态类,但我想创建一个新的GUI组件,要做到这一点,我需要执行该方法的应用程序的主线程。c#回调主线程
我该怎么做?
[注意我不认为我可以使用InvokeRequired作为它的一个静态类不是GUI]
大卫
要弄清这个问题,你有,你想有你的主线程从这个类派生一个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);
}
你的静态类需要在该UI线程上创建了一些实例类的引用,最好一个控件。由于您正在创建一个控件,因此您可能需要为该控件设置一些窗体/窗口,所以无论如何您都需要参考。您可以使用窗体的Invoke()方法来封装一个将在UI线程上创建控件的调用。
您可以将UI控件的一个实例传递给该方法(然后在该方法上调用Invoke),否则将您想要的作为委托进行包装;例如:
static void DoStuff(..., Action<string> updateMessage) {
...
//loop
updateMessage(currentState);
}
有了:
DoStuff(..., msg => this.Invoke((MethodInvoker)delegate{
this.Text = msg;
}));
我不完全确定这会起作用;不是这个静态类无法访问的引用吗?我可能会错过一些上下文。 – OwenP 2010-10-13 22:39:31
@OwenP - 如果你把它作为参数传递给方法,它是完全可访问的... – 2010-10-14 07:05:31
谢谢Salizar,我看到你的解决方案将工作。 – GreyCloud 2010-10-14 08:14:43
只是为了澄清,这个示例仍然需要在事件处理程序中调用,对吗? (正如解决方案中提到的那样)事件本身不会跨线程,对吧? – Marcus10110 2014-09-14 17:46:24