2010-10-13 115 views
2

我在一个后台线程中的静态类,但我想创建一个新的GUI组件,要做到这一点,我需要执行该方法的应用程序的主线程。c#回调主线程

我该怎么做?

[注意我不认为我可以使用InvokeRequired作为它的一个静态类不是GUI]

大卫

回答

7

要弄清这个问题,你有,你想有你的主线程从这个类派生一个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); 
    } 
+0

谢谢Salizar,我看到你的解决方案将工作。 – GreyCloud 2010-10-14 08:14:43

+0

只是为了澄清,这个示例仍然需要在事件处理程序中调用,对吗? (正如解决方案中提到的那样)事件本身不会跨线程,对吧? – Marcus10110 2014-09-14 17:46:24

2

你的静态类需要在该UI线程上创建了一些实例类的引用,最好一个控件。由于您正在创建一个控件,因此您可能需要为该控件设置一些窗体/窗口,所以无论如何您都需要参考。您可以使用窗体的Invoke()方法来封装一个将在UI线程上创建控件的调用。

+0

静态类通过激活器创建一个组件并返回它,所以我没有对gui组件的引用...是唯一的选择重构,所以我做? – GreyCloud 2010-10-13 22:36:31

+0

我想不出一种明确获取UI线程的方法,而不是枚举与进程相关的所有线程并进行疯狂猜测。我查看了Application类和System.Threading.Thread的属性,但似乎没有任何答案。 – OwenP 2010-10-13 22:42:51

+0

+1,因为我已经重构了这个解决方案[在Salizar回答之前]。 – GreyCloud 2010-10-14 08:15:49

1

您可以将UI控件的一个实例传递给该方法(然后在该方法上调用Invoke),否则将您想要的作为委托进行包装;例如:

static void DoStuff(..., Action<string> updateMessage) { 
    ... 
    //loop 
    updateMessage(currentState); 
} 

有了:

DoStuff(..., msg => this.Invoke((MethodInvoker)delegate{ 
    this.Text = msg; 
})); 
+0

我不完全确定这会起作用;不是这个静态类无法访问的引用吗?我可能会错过一些上下文。 – OwenP 2010-10-13 22:39:31

+0

@OwenP - 如果你把它作为参数传递给方法,它是完全可访问的... – 2010-10-14 07:05:31