Удалите необходимость в Invoke (), обработав в поточной библиотеке - PullRequest
4 голосов
/ 22 января 2010

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

    public void DoStuffAsync(AP p)
    {
        this.Running = true;
        this.Cancel = false;

        ParameterizedThreadStart threadStart = new ParameterizedThreadStart(DoStuff);
        Thread procThread = new Thread(threadStart);
        procThread.Start(p);
    }

У меня также есть ряд событий, объявленных в интерфейсе, к которым может подключиться разработчик, таких как StatusUpdate и ProgressUpdate. В настоящее время я пишу небольшое тестовое приложение (в настоящее время в WPF, хотя ожидаю того же поведения в WinForms), которое вызывает DoStuffAsync (), а затем обновляет индикатор выполнения и метку.

К сожалению, 1-й проход Я получил ошибку, обычный поток не является тем, который владеет элементами управления. То, что я хотел бы сделать, это избавить пользователя от необходимости вызывать Invoke () на стороне пользовательского интерфейса, а также просто подписаться на события и заставить их работать.

Итак, вопрос, есть ли способ, которым я могу сделать это мой код при работе с обработчиками событий? На данный момент срабатывает так:

        public void UpdateProgress(object sender, ProgressEventArgs e)
        {
            if (handler != null)
            {
                handler(sender, e);
            }
        }

Ответы [ 2 ]

3 голосов
/ 22 января 2010

Используйте взамен AsyncOperationManager .

Он вызовет вас. (внутренне он использует SynchronizationContext, как описывает nobugz)

3 голосов
/ 22 января 2010

Вам понадобится ссылка на объект Dispatcher клиента, чтобы вы могли вызвать Dispatcher.Invoke или Dispatcher.BeginInvoke, чтобы перенаправить вызов в поток пользовательского интерфейса клиента. Сделайте это, позволив клиенту дать вам нужную ссылку через конструктор или свойство.

Другой способ сделать это - сохранить ссылку на SynchronizationContext.Current в конструкторе вашего класса. Используйте метод Send или Post. Однако для этого требуется, чтобы клиент правильно инициализировал WPF (должен быть вызван Application.Run) и создавал ваш объект класса из его потока пользовательского интерфейса.

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