2010-10-12 66 views
1

我想從一個不同的線程更新UI元素,但我很明顯缺少與新的WPF調用有關的東西。多線程WPF與訪問器

在3.5的WinForms我不喜歡的東西在通過不同的線程更新時,我的UI如下:4.0 WPF現在

public string SummaryTitle 
    { 
    get 
    { 
    if (IsHandleCreated && InvokeRequired) 
    { 
    IAsyncResult result = BeginInvoke(new Func<object, object[], object>(GetType().GetProperty("SummaryTitle").GetValue), this, null); 
    return EndInvoke(result).ToString(); 
    } 

    return myTextBox.Text.Trim(); 
    } 
    set 
    { 
    if (IsHandleCreated && InvokeRequired) 
    { 
    BeginInvoke(new Action<object, object, object[]>(GetType().GetProperty("SummaryTitle").SetValue), this, value, null); 
    } 
    else 
    { 
    myTextBox.Text = value; 
    } 
    } 
    } 

我試圖模仿以上,但隨着新的調度程序(也許有除了調度員之外,還有其他更好的方法嗎?)。這裏是原型代碼我與現在玩(我知道在它仍然nonthreading相關問題,請忽略現在),它是不工作的權利:

 public string SomeText 
    { 
    get { 
    if(!myTextBox.Dispatcher.CheckAccess()) 
    { 
    object o = myTextBox.Dispatcher.Invoke(new Func<object, object[], object>(GetType().GetProperty("SomeText").GetValue), this, null); 
    return o != null ? Convert.String(o) : ""; 
    } 

    return myTextBox.Text.Trim(); 
    } 
    set 
    { 
    if (!myTextBox.Dispatcher.CheckAccess()) 
    { 
    myTextBox.Dispatcher.Invoke(new Action<object, object, object[]>(GetType().GetProperty("SomeText").SetValue),this, value, null); 
    return; 
    } 

    myTextBox.Text = value; 
    } 
    } 

如何使WPF任何幫助訪問器函數類似於舊的3.5 winforms方法將不勝感激。


編輯:我正在尋找更多的辦法,使對用戶界面的訪問器屏幕元素線程安全比線程調用程序或具體進度。訪問者需要能夠從另一個程序集或類執行,而不管該調用類是使用Thread還是BackgroundWorker。此外,它需要爲所有UI元素保留水分,而不僅僅是一個進度條。所以文本框等也可以通過這種方式使線程安全。我更新了這些例子,以幫助更好地傳達我的煩惱。

回答

1

我對WPF還是比較新的,但是每當我使用調度程序時,我都指定要在哪個優先級上運行該操作。這決定行動實際上得到運行

myControl.Dispatcher.BeginInvoke(DispatcherPriority.Render, 
    new Action(delegate() 
    { 
     // Code to execute goes here 
    } 
)); 

可以發現here

它看起來像你想更新進度條...如果你的酒吧勢必東西PriorityLevels列表(比如一個介於0和100之間的數字),您可以將調度程序調用添加到長時間運行的進程中並讓它更新該數字。 DataBinding應該照顧其餘的。

0

我知道你有興趣讓Dispatcher正常工作,但對於這樣的事情,你看過使用BackgroundWorker?儘管對優先級等有一些限制,但它肯定會簡化在更新UI時在後臺線程上運行計算。

這是我幫助某人使用BackgroundWorker的SO thread。當然,如果你使用的是其他線程模型,這可能對你沒有用 - YMMV - 但如果你只是想在更新ProgressBar時在後臺做一些工作,那麼看看。

+0

感謝您的回覆。我目前正在使用背景工作,但是在另一個與上面鬆散耦合的類中。 bg worker是調用上述訪問器的'其他線程'。如果我在沒有調用重定向的情況下調用bgworker的上述訪問,那麼它會拋出你的普通「不能從另一個線程訪問進度條」類型的消息。所以,我試圖重新激活相同的訪問器,但是從當前正在執行的線程中,因爲當前正在執行的線程可能與GUI線程不同。 – 2010-10-12 13:32:08

+0

@John - 不是試圖從DoWork事件/方法更新進度條,而是將BGWorker的WorkerReportsProgress屬性設置爲true,爲其ProgressChanged事件添加事件處理程序,並從DoWork事件處理程序中調用其ReportProgress方法。將用於更新ProgressBar的代碼放入ProgressChanged事件處理程序中。否則,由於您自己正在處理多線程部分,所以沒有任何理由將BackgroundWorker用於任何其他線程模型。 – 2010-10-12 13:49:58