2012-06-21 43 views
1

引述馬克Gravell:多線程調用委託

///...blah blah updating files 
string newText = "abc"; // running on worker thread 
this.Invoke((MethodInvoker)delegate { 
    someLabel.Text = newText; // runs on UI thread 
}); 
///...blah blah more updating files 

我期待與WPF中這樣做,所以不能使用invoke方法。有什麼想法嗎?該線程的東西是做我的頭:/

更詳細

我開始了新的主題,像這樣

Thread t = new Thread (LoopThread); 
t.Start(); 
t.Join(); 

但縱觀LoopThread,我想寫的UI。

UPDATE

感謝喬恩斯基特爲Dispatcher.Invoke位。似乎MethodInvoker也是WinForms。 WPF等同?

UPDATE 2

感謝阿德用於建議代替System.Windows.Forms.MethodInvoker,使用System.Action

(你們是對有關this參數混亂,只需要建立以去除誤差。)

總線,因爲加入SimpleInvoke,現在我上線擊中

Extension method must be defined in a non-generic static class 

public partial class MainWindow : Window 

有什麼想法?

+1

關於編輯:取代'System.Windows.Forms.MethodInvoker'你可以使用'System.Action'。 –

+0

@Adriano謝謝!儘管如此,仍然有問題,請參閱上面的代碼。 – windowskm

+1

2nd編輯:'SimpleInvoke'是一個擴展方法,那麼你不需要'this'作爲第一個參數。函數原型中的'this'只是擴展方法的語法。更改爲'this.SimpleInvoke((=)txtDoor1.Foreground = Brushes.Black);' –

回答

6

在WPF中,您只需使用Dispatcher.Invoke而不是Control.Invoke

DispatcherObject類(WPF類派生自)公開了一個Dispatcher屬性,所以你只需要:

Dispatcher.Invoke((Action) delegate { 
    someLabel.Text = newText; // runs on UI thread 
}); 

如果您使用C#3或更高版本(和.NET 3.5或更高版本),你可能要擴展方法添加到DispatcherObject

// Make this a new top-level class 
public static class DispatcherObjectExtensions 
{ 
    public static void SimpleInvoke(this DispatcherObject dispatcherObject, 
            Action action) 
    { 
     dispatcherObject.Dispatcher.Invoke(action); 
    } 
} 

所以你可以使用:

// From within your UI code 
this.SimpleInvoke(() => someLabel.Text = newText); 
+0

謝謝喬恩。看到我上面的更新。 – windowskm

+0

@killianmcc:沒錯,我沒有發現。我相信WinForms針對MethodInvoker進行了非常小的優化,這就是我懷疑Marc使用它的原因。我已經轉而採取行動,而對於答案中的代碼。無論如何,它更習慣。基本上它並不重要 - 它只是一個無參數的代表。 –

+0

哇看起來比以前好很多。問題雖然:'SimpleInvoke'需要兩個參數,所以我在那裏添加了'this',但仍然拋出一個錯誤。見上面的代碼。 – windowskm

-1

從喬恩斯基特評論繼續,你可以打電話給你的分機像下面

DispatcherObject.SimpleInvoke(() => someLabel.Text = newText); 
+0

不,實際上'SimpleInvoke'是'System.Threading.DispatcherObject'(和派生的)的擴展方法,而不是'System.Threading.Dispatcher'。 –

+0

這是不完整的,並得到糾正。 –

+0

不,你是否嘗試編譯? ;)其實Jon的答案有一個調用示例。 –

0

妥協使用的SynchronizationContext:

// gui thread 

    var sc = SynchronizationContext.Current; 

// work thread 

    sc.Post(s => 
    { 
    someLabel.Text = newText 
    }, null);