views:

40

answers:

2

Hello:

I am trying to execute a Process.Start() that is a long running process, and show a circular progress bar on the screen while the process is executing.

I have the following lines of code:

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

I am new to the threading model and not sure how to implement that for the above. Any help will be greatly appreciated.

Thanks, PJ

+1  A: 

i think , you should give a try to Background worker

And i think , you want to acheive a resposive UI while your Background task is executing.

if this is the caxe , you can make use of Background worker class, i think this class is the most basic class which works beautifully and less complicated to understand if you are a very beginner of threading concepts.

This class exposes events which you can subscribe to handel the long running scenario.

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

    }
}
saurabh
No, I do not want the user to do anything while the execution continues. That is why I am also disabling the screen when the circular progress bar shows up. You can clearly see with my code, it is showing but not rotating.
P N
Saurabh: Can you please provide me with some code snippets for my specific case?
P N
Sure wait for some time , i will post
saurabh
Hi Reed: Thank you for the snippet. I am using .NET 3.5, and I do not think it has the TPL in it.
P N
@P J: You should put this comment on my post, so I see it. That being said, you can do this if you install the Rx extensions here: http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx (It comes with TPL for .NET 3.5). You can also use BW - I'll add that to my post for you...
Reed Copsey
@saurabh: There's no reason for a reset event in this case... The completed event can handle everything on the UI thread automatically...
Reed Copsey
@reed : Correct , we don't need this :) thanks for pointing it out.
saurabh
+1  A: 

Unfortunately, calling:

p.WaitForExit();

Will cause your program execution to block until the spawned executable exits. This will prevent WPF from processing its message pump, which in turn will prevent your progress bar from updating properly.

The normal way to handle this is to disable your UI elements, then spawn the process in a background thread, showing your progress. When the process completes, re-enable the UI elements. Using .NET 4, this could be something like:

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

Alternatively, you can do the same thing via a 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();
Reed Copsey
Thank you very much Saurabh and Reed. Let me try these immediately. I will write back with the result soon.
P N
Hi Reed: It worked exactly the way I wanted. Thank you very much. I really appreciate your help very much.
P N