JLYK
JLYK

Reputation: 391

How to update UI form when process is complete?

So my main form has a button that I enable when this really long copy process is complete. This copy process happens every 10 min and checks for updates etc. I'm stuck on how to get the process to notify the mainform that it's finished copying. Here's what I have so far:

public partial class mainForm : Form
{
 ....//initialize some stuff

    private void TimerEventProcessor(object sender, EventArgs e)
    {
     ....
     copy.GetNewCopy();
    }
}

class Copy
{
   private bool IsCopyComplete;
   ....
   public void GetNewCopy()
   {
       Process proc = new Process();
       IsCopyComplete = false;
       proc.EnableRaisingEvents = true;
       proc.Exited += new EventHandler(myProcess_Exited);
       proc.Start();
   }

   private void myProcess_Exited(object sender, System.EventArgs e)
   {
       IsCopyComplete = true;

       // how to trigger mainform that process is complete?
   }

}

Upvotes: 0

Views: 153

Answers (2)

electricalbah
electricalbah

Reputation: 2297

There are many ways to do this. Here is one

Declare the Handler method in your Mainform and then sunscribe as below

proc.Exited += new EventHandler(MainForm1.myProcess_Exited);

Upvotes: 1

Grant Winney
Grant Winney

Reputation: 66439

You can call Invoke:

private void myProcess_Exited(object sender, System.EventArgs e)
{
    IsCopyComplete = true;

    button1.Invoke(new Action(() => button1.Enabled = true));
}

Here's an article on making thread-safe calls to the UI.

There are several ways to create a thread. My favorite, due to its built-in functionality for updating the UI, is the BackgroundWorker Thread. (Though it's not the right tool for every situation).


You could pass a reference of the form to the class, though that usually seems wrong somehow. The class shouldn't be aware of your form's UI components.

What I'd do is create an EventHandler that the Exited event can publish to. (You can attach to multiple events, so if you still need to set IsCopyComplete = true, then just leave that event too.) When the Exited event fires, it'll call the "ProcessExited" EventHandler without knowing whether anything else subscribed to it.

class Copy
{
    public event EventHandler ProcessExited;

    private bool IsCopyComplete;
    ....
    public void GetNewCopy()
    {
        Process proc = new Process();
        IsCopyComplete = false;
        proc.EnableRaisingEvents = true;
        proc.Exited += ProcessExited;
        proc.Exited += new EventHandler(myProcess_Exited);
        proc.StartInfo = new ProcessStartInfo("cmd.exe"); // specify your process - replace cmd.exe with whatever's appropriate
        proc.Start();
    }

    private void myProcess_Exited(object sender, System.EventArgs e)
    {
        IsCopyComplete = true;
    }
}

Then in your main form, you can subscribe to the event.

public partial class mainForm : Form
{
    ....//initialize some stuff

    public class mainForm()
    {
        ...
        // not sure where you're instantiating `copy` - you may have to move this

        copy.ProcessExited += (s, a) =>
            button1.Invoke(new Action(() => button1.Enabled = true));
        ...
    }

    private void TimerEventProcessor(object sender, EventArgs e)
    {
        copy.GetNewCopy();
    }
}

Upvotes: 1

Related Questions