Потоки WPF для мониторинга Process.Start и отображения индикатора выполнения - PullRequest
2 голосов
/ 11 октября 2010

Я пытаюсь выполнить Process.Start (), который является длительным процессом, и отображать круглую строку прогресса на экране во время выполнения процесса.

У меня есть следующие строки кода:

Process p =
   Process.Start(longRunningProcess);

   // show the circular progress bar;

   ShowHideCirProgBar(true);

   // wait till the process ends execution

   p.WaitForExit();

   // hide the circular progress bar

   ShowHideCirProgBar(false);

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

Спасибо, PJ

Ответы [ 2 ]

3 голосов
/ 11 октября 2010

К сожалению, звоню:

p.WaitForExit();

Заставит выполнение вашей программы блокироваться до тех пор, пока не будет запущен вызываемый исполняемый файл. Это не позволит WPF обработать свой обработчик сообщений, что, в свою очередь, помешает правильному обновлению индикатора выполнения.

Обычный способ справиться с этим - отключить элементы пользовательского интерфейса, а затем запустить процесс в фоновом потоке, показывая ваш прогресс. Когда процесс завершится, снова включите элементы пользовательского интерфейса. Используя .NET 4, это может быть что-то вроде:

// Add code to disable UI, if required
DisableUI();

// Show the circular progress bar;
ShowHideCirProgBar(true);

// Wait till the process ends execution in a background thread
var task = Task.Factory.StartNew( () =>     
    {
        Process p = Process.Start(longRunningProcess);
        p.WaitForExit();
    });

// Reenable the UI when the process completes...
task.ContinueWith( t =>
    {
        EnableUI();

        // hide the circular progress bar
        ShowHideCirProgBar(false);
    }, TaskScheduler.FromCurrentSynchronizationContext());

В качестве альтернативы, вы можете сделать то же самое через BackgroundWorker:

BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (s, e) =>
    {
        Process p = Process.Start(longRunningProcess);
        p.WaitForExit();
    };
bw.RunWorkerCompleted += (s, e) =>
    {
        EnableUI();

        // hide the circular progress bar
        ShowHideCirProgBar(false);
    };

// Add code to disable UI, if required
DisableUI();

// Show the circular progress bar;
ShowHideCirProgBar(true);
bw.RunWorkerAsync();
2 голосов
/ 11 октября 2010

Я думаю, вы должны попробовать Фоновый работник

И я думаю, вы хотите получить Resposive UI во время выполнения фоновой задачи.

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

Этот класс предоставляет события, на которые вы можете подписаться, чтобы отменить длительный сценарий.

  class ThreadingWithBg
{
    BackgroundWorker bg = null;


    public ThreadingWithBg()
    {
        bg = new BackgroundWorker();
        bg.DoWork += new DoWorkEventHandler(bg_DoWork);
        bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);

    }

    void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {


     }

    void bg_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < 100000; i++)
        {
            Console.WriteLine(i.ToString());

        }
    }

    public void DoLongWork()
    {
        bg.RunWorkerAsync();

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