ждать, пока один вызов функции завершит c # - PullRequest
0 голосов
/ 03 июля 2018

В моем приложении у меня есть две кнопки:

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

и метод запуска установки:

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

Проблема: если пользователь нажимает одну кнопку и сразу нажимает вторую, выдается ошибка, которую я не могу установить одновременно.

Мой вопрос: я хочу, чтобы второй вызов метода RunSilentSetup ожидал до тех пор, пока первый вызов не завершится, как мне этого добиться?

изменить код установки:

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

Ответы [ 4 ]

0 голосов
/ 03 июля 2018

Может быть, вы можете определить свойство флага и включить, отключить кнопку, когда она занята

 public bool IsBusyInstalling
    {
        get
        {
            return _isBusyInstalling;
        }
        private set
        {
            _isBusyInstalling = value;
            RaisePropertyChanged("IsBusyInstalling");
        }
    }

и простой стиль:

 <Style TargetType="Button">
       <Style.Triggers>
              <DataTrigger Binding="{Binding Path=IsBusyInstalling}" Value="True">
                   <Setter Property="IsEnabled" Value="False"/>
               </DataTrigger>
        </Style.Triggers>
   </Style>
0 голосов
/ 03 июля 2018

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

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

Есть разные способы сделать это, но это самый простой, который я могу придумать.

Теперь, когда вызывается RunSilentSetup, он сначала проверяет, является ли setupIsRunning истинным. Если это так, он вернется (без дальнейшего выполнения метода RunSilentSetup.

Если нет, для setupIsRunning устанавливается значение true - для прекращения последующих вызовов.

Когда закончено, setupIsRunning возвращается в false.

0 голосов
/ 03 июля 2018

Просто, если это WPF, создайте bool IsWorking, затем преобразуйте его в свойство кнопки с помощью конвертера привязок, и ваша проблема решена ^^

0 голосов
/ 03 июля 2018

Вы можете отключить вторую кнопку, пока первая кнопка не будет нажата

(или)

Вы также можете проверить эту ссылку, чтобы получить какие-либо идеи Ожидание завершения метода

...