用于监视Process.Start和显示进度条的WPF线程

时间:2010-10-11 14:36:10

标签: c# wpf multithreading

我正在尝试执行一个长时间运行的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 个答案:

答案 0 :(得分:3)

不幸的是,请致电:

p.WaitForExit();

将导致程序执行被阻塞,直到生成的可执行文件退出。这将阻止WPF处理其消息泵,这反过来将阻止您的进度条正确更新。

处理此问题的常用方法是禁用UI元素,然后在后台线程中生成进程,显示进度。该过程完成后,重新启用UI元素。使用.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();

答案 1 :(得分:2)

我认为,您应该尝试Background worker

我认为,您希望在执行后台任务时实现一个转发用户界面。

如果这是caxe,你可以使用Background worker类,我认为这个类是最基本的类,如果你是一个非常初学的线程概念,它可以很好地工作,也不太复杂。

此类公开了您可以订阅长期运行场景的事件。

  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();

    }
}