在多线程WPF应用程序中创建LinearGradientBrush时出现InvalidOperationException

时间:2010-10-19 19:39:49

标签: c# wpf multithreading mvvm invalidoperationexception

static C#方法中,我执行var brush = new LinearGradientBrush(_snazzyGradient);,此行抛出异常。 _snazzyGradient定义如下:

private static readonly GradientStopCollection _snazzyGradient =
    new GradientStopCollection
    {
        new GradientStop((Color)ColorConverter.ConvertFromString("#DBF3FF"), 0.0),
        new GradientStop((Color)ColorConverter.ConvertFromString("#A3CCE0"), 1.0)
    };

包含方法和_snazzyGradient实现INotifyPropertyChanged的类,如果重要,并用作视图模型。使用_snazzyGradient的静态方法在类的构造函数中调用。在UserControl类中,我使用引用_snazzyGradient的构造函数将依赖项属性的值设置为该视图模型类的新实例。

当我调试我的应用时,在var brush = new LinearGradientBrush(_snazzyGradient);行,我收到以下异常:

  

发现了System.InvalidOperationException     Message =调用线程无法访问此对象,因为另一个线程拥有它。     来源= WindowsBase     堆栈跟踪:          在System.Windows.Threading.Dispatcher.VerifyAccess()          在System.Windows.Threading.DispatcherObject.VerifyAccess()          在System.Windows.Freezable.ReadPreamble()          在System.Windows.Media.GradientStopCollection.OnInheritanceContextChangedCore(EventArgs args)          在System.Windows.DependencyObject.OnInheritanceContextChanged(EventArgs args)          在System.Windows.Freezable.AddInheritanceContext(DependencyObject context,DependencyProperty property)          在System.Windows.DependencyObject.ProvideSelfAsInheritanceContext(DependencyObject doValue,DependencyProperty dp)          在System.Windows.DependencyObject.ProvideSelfAsInheritanceContext(Object value,DependencyProperty dp)          在System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex,DependencyProperty dp,PropertyMetadata metadata,EffectiveValueEntry oldEntry,EffectiveValueEntry& newEntry,Boolean coerceWithDeferredReference,OperationType operationType)          在System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp,Object value,PropertyMetadata metadata,Boolean coerceWithDeferredReference,OperationType operationType,Boolean isInternal)          在System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp,Object value)          在System.Windows.Media.LinearGradientBrush..ctor(GradientStopCollection gradientStopCollection)          在LoadedTemplate.getBackgroundForTemplateValue(String fieldName)          在LoadedTemplate..ctor(ParentViewModel viewModel,Template template)          在Form.LoadTemplate(模板模板)     InnerException:

我已经将UserControl中的依赖项属性更改为以下内容:

public ParentViewModel Data
{
    get
    {
        return (ParentViewModel)Dispatcher.Invoke(
            DispatcherPriority.Background,
            (DispatcherOperationCallback)delegate
            {
                return GetValue(DataProperty);
            },
            DataProperty
        );
    }
    set
    {
        Dispatcher.BeginInvoke(
            DispatcherPriority.Background,
            (SendOrPostCallback)delegate
            {
                SetValue(DataProperty, value);
            },
            value
        );
    }
}

我的问题是,如何摆脱这个InvalidOperationException?在我的视图模型中放置一堆与Dispatcher线程相关的调用似乎是不对的。我不应该将_snazzyGradient定义为静态字段,但是可能从静态方法返回它吗?我不知道这是否有帮助。我绝对想要多线程,因为我不希望在读取/写入必要的文件时,GUI陷入困境。也许我的问题源于在视图模型中使用GradientStop(继承自DependencyObject)等;也许那些应该从我的UserControl

提供给视图模型的构造函数

1 个答案:

答案 0 :(得分:0)

好的,看起来将_snazzyGradientstatic字段移到static方法工作:

private static GradientStopCollection getSnazzyGradient()
{
    return new GradientStopCollection
    {
        new GradientStop((Color)ColorConverter.ConvertFromString("#DBF3FF"), 0.0),
        new GradientStop((Color)ColorConverter.ConvertFromString("#A3CCE0"), 1.0)
    };
}

我猜这是因为GradientStop以某种方式,因为它是DependencyObject的子节点,因为我的UserControl类,并且依赖项对象具有线程亲和性。现在做var brush = new LinearGradientBrush(getSnazzyGradient());工作正常,没有抛出异常。