Конвертировать диспетчер WPF в Winforms BGworker?

Я недавно приобрел некоторый исходный код для оболочки консоли для сервера. Программа была первоначально в WPF, и часть кода была:

<code>    private void ServerProc_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        Dispatcher.Invoke(new Action(() =>
        {
            ConsoleTextBlock.Text += e.Data + "\r\n";
            ConsoleScroll.ScrollToEnd();
        }));
    }
    private void ServerProc_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Dispatcher.Invoke(new Action(() =>
        {
            ConsoleTextBlock.Text += e.Data + "\r\n";
            ConsoleScroll.ScrollToEnd();
            ParseServerInput(e.Data);
        }));
    }
</code>

У этого также была эта аннотация в обеих пустотах:

// You have to do this through the Dispatcher because this method is called by a different Thread

Однако в WinForms нет такой вещи - есть ли способ изменить это на Фоновый рабочий или что-то еще (я только что сделал многопоточность)?

Если кто-то может помочь, это будет здорово!

Благодарю.

Ответы на вопрос(2)

Немного предыстории: процессу, который выполняется в потоке, отличном от потока пользовательского интерфейса, не разрешен прямой доступ к любым элементам управления пользовательского интерфейса. Ваш WPF ServerProc работает в другом потоке, чем ваш пользовательский интерфейс, который требуетDispatcher чтобы помочь вам общаться из потока ServerProc обратно к элементам управления пользовательского интерфейса в вашем потоке пользовательского интерфейса.

Если ваш ServerProc - в WPF или WinForms - работал в потоке пользовательского интерфейса, вам не нужно было бы окружать егоDispatcher.Invoke вызов.

Для вас вы можете поместить свой ServerProc вBackgroundWorker (пример MSDN), ВашDoWork метод будет содержать основную часть кода, выполняющего работу, а затем, в зависимости от того, как ServerProc работает, вы можете использоватьProgressChanged чтобы сделать то, что делают оба ваших примера методов WPF.ProgressChanged имеет переданный параметр, который вы указали бы, если это была ошибка или были получены данные, и внутри функции вы могли бы отображать соответствующую информацию. Посмотрите на документы MSDN, потому что у них есть хороший пример.

Важно отметить, чтоProgressChanged происходит в потоке пользовательского интерфейса, поэтому вам НЕ нужно окружать свои вызовы элементами управления пользовательским интерфейсом с помощью Invoke; просто позвони им нормально. То же самое касаетсяRunWorkerCompleted это может быть другой вариант для отображения данных, когда ваш ServerProc завершил свою работу.

Наконец, если вам действительно нужно было получить доступ к элементу управления пользовательского интерфейса из вашего потока, вы делаете что-то очень похожее на ваш пример кода WPF. смотреть наMethodInvoker, Вместо Dispatcher вы на самом деле просто вызываете его из своей основной формы.

 Alex Ogden07 апр. 2012 г., 15:14
СПАСИБО ОГРОМНОЕ! ; D Я использовал метод invoker! Нет, я наконец смогу запустить это приложение. Большая помощь. Благодарю.
 07 апр. 2012 г., 15:14
Проблема заключается в том, что оба метода ServerProc являются обработчиками событий и будут вызываться существующим кодом в потоке без пользовательского интерфейса. Я точно уверен, как BackgroundWorker может помочь в этом случае? Я не думаю, что он хочет переписать существующий код прослушивания сервера / запуска событий - только обработчики событий - они уже есть в потоке без пользовательского интерфейса.
 08 апр. 2012 г., 10:26
@AlexOgden Если это предоставило вам решение, отметьте его как принятый ответ, щелкнув галочку слева.

Оба метода являются обработчиками событий. Скорее всего, они из какого-то кода прослушивания, и я ожидаю, что они вызываются из потока, не являющегося пользовательским интерфейсом (например, обычно из потока пула, который выполняет прослушивание). Вы можете проверить это, установив точку останова и посмотрев на окно потоков в отладчике.
Поэтому вам нужно будет применить способ winforms для обновления пользовательского интерфейса из потока, не являющегося пользовательским интерфейсом.
Если вы ищете SO, вы должны найти довольно много о том, как это сделать. Например
Обновление интерфейса из другого потока
Как обновить графический интерфейс из другого потока в C #?

 Alex Ogden07 апр. 2012 г., 15:08
Спасибо, но я не совсем уверен, как я могу применить это к своему коду - я намного лучше с VB.NET, все еще привыкаю к C #

Ваш ответ на вопрос