PictureBox зависает при выполнении процесса - PullRequest
0 голосов
/ 28 ноября 2018

У меня проблема с PictureBox после выполнения процесса.В то время, когда я вызываю процесс, который просто выполняет пакетный файл, PictureBox (отображает анимацию GIF) останавливается.

Я хочу нажать кнопку, которая запускает процесс, и показать PictureBox, отображающий анимацию GIF,и после завершения процесса я хочу скрыть PictureBox.

Кто-нибудь знает, как этого добиться?

Вот мой код:

// My executeCmdCommand
public void executeCmdCommand(string argument)
{
    var arg0 = argument; // Path

    System.Diagnostics.Process process = new System.Diagnostics.Process();
    System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
    startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    startInfo.FileName = "cmd.exe";
    startInfo.Arguments = "/C " + arg0;
    process.StartInfo = startInfo;

    process.Start();
    process.WaitForExit();
}

private void button1_Click(object sender, EventArgs e)
{
    DisplayImage();
    string cmdCom = @"C:\Users\Mim\Desktop\test.bat";
    executeCmdCommand(cmdCom);
    HideImage();
}

private void DisplayImage()
{
    imageControl.Show();
    //PictureBox imageControl = new PictureBox();
    imageControl.Width = 400;
    imageControl.Height = 400;
    Bitmap image = new Bitmap(@"C:\Users\foobar\Desktop\loading.gif");
    imageControl.Dock = DockStyle.Fill;
    imageControl.Image = (Image)image;
    Controls.Add(imageControl);
}

private void HideImage()
{
    imageControl.Hide();
}

1 Ответ

0 голосов
/ 28 ноября 2018

Проблема заключается в этой строке кода внутри вашей executeCmdCommand() функции:

process.WaitForExit();

Посмотрите, что в документации говорится об этом методе:

Process.WaitForExit Method |Документы Microsoft

Устанавливает период времени для ожидания завершения связанного процесса, а блокирует текущий поток выполнения до тех пор, пока не истечет время или процесс не завершится.Чтобы не блокировать текущий поток, используйте событие Exited .

Поэтому не следует вызывать этот метод, если вы хотите, чтобы поток пользовательского интерфейса был разблокирован до конца выполнения внешнего процесса,Но если вы все еще хотите получить предупреждение о завершении процесса, вы можете использовать событие Exited, как указано в документации.

Вы можете найти пример использования события Exited идругие идеи, здесь:

Форма Windows запускает внешний процесс без блокировки пользовательского интерфейса - Переполнение стека

Я бы добавил только одну вещь к ответу, чтоЯ только что связался: если вы собираетесь скрыть свой PictureBox в обработчике события, вызываемом событием Process.Exited, вы должны установить ссылку вашего Form на свойство Process.SynchronizingObject ( документация ), иначе ваш обработчик событий может (в основном, вероятно) выполняться в потоке, отличном от вашего потока пользовательского интерфейса, вызывая ошибку при доступе к чему-либо из вашего Form, включая элементы управления.

Код может выглядеть следующим образом:

using System.Diagnostics;

public void executeCmdCommand(string argument)
{
    Process process = new System.Diagnostics.Process();
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.FileName = "cmd.exe";
    startInfo.Arguments = $"/C {argument}";
    process.StartInfo = startInfo;

    process.EnableRaisingEvents = true;
    process.SynchronizingObject = this;
    process.Exited += (sender, e) => {
       HideImage();
    };  

    process.Start();
    //process.WaitForExit();
}
...