C # WPF Выполнить действие, когда окно будет создано

#c# #wpf #multithreading #progress-bar

#c# #wpf #многопоточность #индикатор выполнения

Вопрос:

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

Код действия, который открывает окно :

 private void button_Run_Click(object sender, RoutedEventArgs e)
{
        ExecutorWindow myExecWindow = new ExecutorWindow();
        myExecWindow.Show();
}
  

Код окна :

 public partial class ExecutorWindow : Window
{
    BackgroundWorker execBackground = new BackgroundWorker();

    public ExecutorWindow()
    {
        InitializeComponent();
        RunExecutor();
    }

    public void RunExecutor()
    {
        // CREATE BACKGROUNDWORKER FOR EXECUTOR
        execBackground.DoWork  = new DoWorkEventHandler(execBackground_DoWork);
        execBackground.RunWorkerCompleted  = new RunWorkerCompletedEventHandler(execBackground_RunWorkerCompleted);
        execBackground.WorkerReportsProgress = true;
        execBackground.WorkerSupportsCancellation = true;
        // RUN BACKGROUNDWORKER
        execBackground.RunWorkerAsync();
    }

    private void execBackground_DoWork(object sender, DoWorkEventArgs e)
    {
        // CREATE EXECUTOR INSTANCE
        Executor myExecutor = new Executor(arg1, arg2);
        myExecutor.RunWhileRemainMachines();
    }

    private void execBackground_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show("RunWorkerCompleted execBackground");
    }
}
  

Но что происходит, так это то, что RunProcessingJob вызывается только тогда, когда я закрываю окно (что нормально, потому что я запускаю его после ShowDialog). Я пытался вызвать его из общедоступной функции ExecutorWindow(), но тогда получается наоборот: окно открывается только после завершения RunProcessingJob.

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

Должен ли я запускать свое задание по обработке в BackgroundWorker, вызываемом в общедоступном ExecutorWindow () ?

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

РЕДАКТИРОВАТЬ: я обновил свой код на основе ваших комментариев (запуск непосредственно моего окна без создания другого потока. Кроме того, я запускаю свое задание обработки из конструктора window, но теперь в отдельном потоке, чтобы предотвратить проблемы с блокировкой, которые у меня были).

Ответ №1:

Это полностью зависит от того, что Executor.RunProcessingJob делает; на вопрос нельзя ответить, не посмотрев на этот код.

Однако, почему вы создаете ExecutorWindow в другом потоке? Если вы хотите, чтобы оно оставалось отзывчивым на пользовательский ввод, у вас нет другого выбора, кроме как выполнить вашу обработку в еще одном потоке (вы упомянули BackgroundWorker , так что это, вероятно, уже происходит). Но если вы сделаете это, в первую очередь, нет необходимости создавать ExecutorWindow в своем собственном потоке.

Комментарии:

1. Привет, Джон, задание Runprocessing создает несколько фоновых рабочих, которые выполняют некоторые сетевые операции (задержка выполнения может варьироваться от 60 секунд до 5 минут). Одновременно выполняется X фоновых программ (X определено ранее) и дождитесь завершения работы фоновой программы, прежде чем запускать другую. Как только все они будут запущены, оно вернется. В идеале я хотел бы обновлять панель выполнения в моем ExecutorWindow каждый раз, когда один из этих фоновых рабочих завершает работу или сообщает о прогрессе.

Ответ №2:

Я думаю, вам следует запустить поток обработки в вашем классе ExecutorWindow. Подключите его к какому-либо событию, например, к загрузке. Также я не думаю, что вам нужен отдельный поток для создания и отображения вашего ExecutorWindow. (Если вы не хотите модальный диалог, просто вызовите Show() вместо ShowDialog())

Ответ №3:

Переопределите ExecutorWindow метод OnInitialize

 protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);
        RunExecutor();
    }