我在一個後臺線程中的靜態類,但我想創建一個新的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