Пользовательские события и потоки - PullRequest
1 голос
/ 29 марта 2012

У меня есть два разных проекта, и в одном у меня есть класс, который определяет настраиваемое событие для запуска при определенных условиях:

  public delegate void ButtonHandler(object myObject,
                                           GuitarArgs myargs);

        public event ButtonHandler OnButtonPress;

... other stuff ...

  GuitarArgs myArgs = new GuitarArgs( guitarState );
                if(OnButtonPress!= null)
                     OnButtonPress(this, myArgs);

Затем в другом проекте я создаю экземпляр этого класса и подписываюсь на это событие:

Guitar.OnButtonPress += Guitar_OnButtonPress;

Событие затем запускается правильно, но, похоже, оно происходит в другом потоке, потому что, когда я пытаюсь получить доступ к некоторым элементам пользовательского интерфейса, я получаю сообщение об ошибке: вызывающий поток не может получить доступ к этому объекту, поскольку другой поток владеет им. *

Код, выдавший ошибку:

 void Guitar_OnButtonPress(object myObject, Guitar.GuitarArgs myargs)
        {
            GuitarCheck(myargs.State);
        }

        private void GuitarCheck(GuitarState getState)
        {
                if (getState.green) 
                {
                    VisualTreeHelper.HitTest(guitarCanvas, null,
                                             MyHitTestResult,
                                             new GeometryHitTestParameters(
                                                 new RectangleGeometry(new Rect(1, 411, 88, 78))));
                }
}

Что я могу сделать, чтобы запустить?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 29 марта 2012

Вам необходимо проверить, работает ли ваш обработчик событий в потоке, не являющемся пользовательским интерфейсом, и, если это так, вызвать его в потоке пользовательского интерфейса:

Как обновить графический интерфейс из другого потока в C #?

Я хотел бы выделить ответ с меньшим количеством голосов, который обеспечивает очень элегантный подход с использованием метода расширения.Я использую это во всех моих проектах WinForms (и использую вариант в проектах WPF / Silverlight)

https://stackoverflow.com/a/3588137/141172

1 голос
/ 29 марта 2012

Если вы используете WinForms this.Invoke(() => GuitarCheck(myargs.State)); (http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx)

Если вы используете WPF this.Dispatcher.Invoke(() => GuitarCheck(myargs.State)); (http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invoke.aspx)

0 голосов
/ 29 марта 2012

Итак, у вас есть событие с именем OnButtonPress, чей обработчик событий явно выполняется в потоке, который не содержит VisualTreeHelper.Большой вопрос для меня ... почему?С таким именем, как OnButtonPress, я думаю, что оно уже должно быть в потоке пользовательского интерфейса.В конце концов, это нажатие кнопки, верно?Итак, почему выполняется в другом потоке для начала?

Использование операции маршалинга, такой как Invoke или BeginInvoke, хорошо, если вы знаете, почему она необходима, ичто это делает для вас.Но вам действительно нужно сделать шаг назад и определить, что происходит, что заставит вас нуждаться в , чтобы сначала использовать операцию маршалинга.Здесь может быть более серьезная проблема, которую вам нужно решить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...