Search code examples
c#wpfwait

wait for one function call would finish c#


In my app I have two buttons:

void Install_1_Click(object sender , RoutedEventArgs e)
{
 RunSilentSetup("C:\app1.exe");
}
.
.
.
void Install_2_Click(object sender , RoutedEventArgs e)
{
 RunSilentSetup("C:\app2.exe");
}

and the method that runs the setup:

void RunSilentSetup(string executableFilePath)
{
 //code that runs the setup goes here
}

The problem: if the user clicks one button and immediately press the second, it throw error that I can't install simultaneously.

My question: I want that the second call to method RunSilentSetup will wait intill the first call will finish, how can I achieve that?

edit installation code:

   try
        {
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.CreateNoWindow = false;
            startInfo.UseShellExecute = true;
            startInfo.FileName = executableFilePath;
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            startInfo.Arguments = "/s /v/qn";
            using (Process exeProcess = Process.Start(startInfo))
            {
                exeProcess.WaitForExit();
                int exitcode = exeProcess.ExitCode;

                if (exitcode == 0)
                    this.Dispatcher.Invoke(() =>
                    {
                        ShowMessage(_vm.ShowSuccess , "Installation was successfully completed");
                    });
                else
                    this.Dispatcher.Invoke(() =>
                    {
                        ShowMessage(_vm.ShowError , $"one or more errors occurred during the installation, exit code: {exitcode}");
                    });
            }
        } catch (Exception ex)
        {
            log.Warn(ex);
        }

Solution

  • You could add a static isRunning type field like this:

    void Install_1_Click(object sender , RoutedEventArgs e)
    {
        RunSilentSetup("C:\app1.exe");
    }
    
    void Install_2_Click(object sender , RoutedEventArgs e)
    {
        RunSilentSetup("C:\app2.exe");
    }
    
    static bool setupIsRunning = false;
    
    void RunSilentSetup(string executableFilePath)
    {
        if(setupIsRunning)
            return;
    
        setupIsRunning = true;
        //disable both buttons
        Install_1.Enabled = false;
        Install_2.Enabled = false;
    
        //code that runs the setup goes here
    
        setupIsRunning = false; //set back to false when finished
    
        //re-enable both buttons
        Install_1.Enabled = true;
        Install_2.Enabled = true;
    }
    

    There's different ways of doing this, but this is the most simple I can come up with.

    Now, when RunSilentSetup is called, it fist checks to see if setupIsRunning is true. If it is, it will return (without further executing the RunSilentSetup method.

    If not, it sets setupIsRunning to true - to stop subsequent calls.

    When finished, setupIsRunning is set back to false.