InvalidOperationException при создании LinearGradientBrush в многопоточном приложении WPF - PullRequest
0 голосов
/ 19 октября 2010

В методе 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 = Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им.Source = WindowsBase StackTrace: в System.Windows.Threading.Dispatcher.VerifyAccess () в System.Windows.Threading.DispatcherObject.VerifyAccess () в System.Windows.Freezable.ReadPreamble () в System.Windows.Media.GradientStopColitedConite (onCherint.OnIn)Аргументы EventArgs) в System.Windows.DependencyObject.OnInheritanceContextChanged (EventArgs args) в System.Windows.Freezable.AddInheritanceContext (контекст DependencyObject, свойство DependencyProperty) в System.Windows.DependencyObject.PerdencyDenceTentInject.ProjectDextIn (DependencyObject.ProvideSelfAsInheritanceContext (значение объекта, DependencyProperty дп) при System.Windows.DependencyObject.UpdateEffectiveValue (EntryIndex entryIndex, DependencyProperty Д.П., PropertyMetadata метаданных, EffectiveValueEntry oldEntry, EffectiveValueEntry & newEntry, булевой coerceWithDeferredReference, OperationType operationType) в System.Windows.DependencyObject.SetValueCommon (DependencyProperty dp, значение объекта, метаданные PropertyMetadata, логическое значение coerceWithDeferredReference, OperationType operationType, логическое значение isInternal) в System.Windows.DependencyObject.SetValueInternal (DependencyProperty dp, значение объекта) в System.Windows.Ttop..getBackgroundForTemplateValue (String fieldName) в LoadedTemplate..ctor (ParentViewModel viewModel, Template template) в Form.LoadTemplate (Template template) 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 голосов
/ 20 октября 2010

Хорошо, похоже на перемещение _snazzyGradient из поля static в 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()); работает нормально, без исключений.

...