WPF Calling thread Access object error

时间:2018-06-04 17:21:57

标签: wpf thread-safety

Getting Calling thread Access object error. Been reviewing solutions but can't seem to get it right. The lines ButtonPark and LabelState both throw the error. Any help appreciated.

public static class TelescopeHardware
{
    public static event PropertyChangedEventHandler StaticPropertyChanged;
    private static void OnStaticPropertyChanged(string propertyName)
    {
        var handler = StaticPropertyChanged;
        handler?.Invoke(null, new PropertyChangedEventArgs(propertyName));
    }
}
public partial class MainWindow
{
        private void Window_Load(object sender, RoutedEventArgs e)
        {
        TelescopeHardware.StaticPropertyChanged += PropertyChanged;
    }
    private void PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
        case "SiderealTime":
            TextLst.Text = _util.HoursToHMS(TelescopeHardware.SiderealTime);
            break;
        case "RightAscension":
            TextRa.Text = _util.HoursToHMS(TelescopeHardware.RightAscension);
            break;
        case "Declination":
            TextDec.Text = _util.HoursToHMS(TelescopeHardware.Declination);
            break;
        case "AtPark":
            ButtonPark.Content = TelescopeHardware.AtPark ? @"UnPark" : @"Park";
            LabelState(TextParked, TelescopeHardware.AtPark);
            break;
                }
            }
    }
    private void LabelState(TextBlock text, bool state)
    {
        var brush = state ? new SolidColorBrush(Colors.GreenYellow) : new SolidColorBrush(Colors.DimGray);
        text.Foreground = brush;
    }
}

1 个答案:

答案 0 :(得分:1)

The TelescopeHardware.StaticPropertyChanged is most likely raised on thread that is not the UI thread so the handler should switch to the UI thread:

private void PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    this.Dispatcher.BeginInvoke((Action)(()=>
    {
        switch (e.PropertyName)
        {
            case "SiderealTime":
                TextLst.Text = _util.HoursToHMS(TelescopeHardware.SiderealTime);
                break;
            case "RightAscension":
                TextRa.Text = _util.HoursToHMS(TelescopeHardware.RightAscension);
                break;
            case "Declination":
                TextDec.Text = _util.HoursToHMS(TelescopeHardware.Declination);
                break;
            case "AtPark":
                ButtonPark.Content = TelescopeHardware.AtPark ? @"UnPark" : @"Park";
                LabelState(TextParked, TelescopeHardware.AtPark);
                break;
        }
    }));
}