2010-12-09 82 views
8

我在實現System.ComponentModel.INotifyPropertyChanged一個基類下面的方法:.NET無法執行此操作

protected virtual void RaisePropertyChangedEventSynchronous(string propertyName) 
{      
    try 
    { 
     if (PropertyChanged != null) 
     { 
      Delegate[] delegates = this.PropertyChanged.GetInvocationList(); 
      foreach (PropertyChangedEventHandler handler in delegates) 
      {      
       try 
       { 
        DispatcherObject dispatcherInvoker = handler.Target 
         as DispatcherObject; 
        if (dispatcherInvoker != null) 
        {         
         dispatcherInvoker.Dispatcher.Invoke(DispatcherPriority.Normal, 
          new Action(delegate 
         { 
          handler(this, new PropertyChangedEventArgs(propertyName)); 
         })); 
        } 
        else 
        { 
         handler(this, new PropertyChangedEventArgs(propertyName)); 
        } 
       } 
       catch (Exception ex) 
       {      
        ExceptionPolicy.HandleException(ex, 
         ExceptionHandlingPolicyNames.LogPolicy); 
       } 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     ExceptionPolicy.HandleException(ex, ExceptionHandlingPolicyNames.LogPolicy); 
    } 
} 

有時,我會得到記錄到文件中出現以下異常:

類型:System.InvalidOperationException,mscorlib,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089 消息:暫停調度程序處理時無法執行此操作。 來源:WindowsBase 幫助鏈接:在System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame幀) 於: 數據:System.Collections.ListDictionaryInternal TargetSite:空隙PushFrame(System.Windows.Threading.DispatcherFrame) 堆棧跟蹤System.Windows.Threading.DispatcherOperation.Wait(TimeSpan timeout) at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority,TimeSpan timeout,Delegate method,Object args,Boolean isSingleParameter) at System.Windows.Threading.Dispatcher。在OCC600.Infrastructure.Dictionary.BusinessEntities.Observable.RaisePropertyChangedEventSynchronous(String propertyName)中調用(DispatcherPriority優先級,委託方法)

如果我使用Dispatcher.BeginInvoke來更新UI,我不會看到這些異常。但是我發現使用BeginInvoke執行更新是不可靠的,因爲有時這些更改不會反映在用戶界面上。

我該如何解決這個問題?

回答

8

我認爲你在後臺線程,並試圖在UI線程上引發你的PropertyChanged事件。我認爲WPF會爲您處理線程更改;你不應該這樣做。

這是我寫的一些代碼。 XAML:

<Window x:Class="WpfApplication2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
    <TextBlock Text="{Binding Value}" /> 
    </Grid> 

C#:

public partial class MainWindow : Window { 
    public MainWindow() { 
    InitializeComponent(); 

    this.DataContext = new Backgrounder(); 
    } 

    class Backgrounder : INotifyPropertyChanged { 
    int value = 0; 
    public Backgrounder() { 
     ThreadPool.QueueUserWorkItem(o => { 
     while (true) { 
      this.value++; 
      Notify("Value"); 
      Thread.Sleep(TimeSpan.FromSeconds(1)); 
     } 
     }); 
    } 

    public int Value { get { return this.value; } } 

    public event PropertyChangedEventHandler PropertyChanged; 

    void Notify(string property) { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) { 
     handler(this, new PropertyChangedEventArgs(property)); 
     } 
    } 
    } 
} 
+1

謝謝你,謝謝你。這應該很簡單。然而,要刷新集合,我必須對CollectionView.Refresh()方法執行dispatcher.invoke,否則會引發異常。 – 2010-12-10 14:14:51

相關問題