Многопоточность - прерывание потока при событии WinForms - PullRequest
0 голосов
/ 18 января 2019

Я работаю над проектом C # WinForms, в котором реализован менеджер паролей. Одной из функций, которые я хочу включить, является тайм-аут на то, как долго пароль может оставаться в системном буфере обмена. Я реализовал поток, который обновляет индикатор выполнения и затем очищает буфер обмена, прежде чем поток завершается:

private void getPassword(int lifeInSeconds)
    {
        int maxLifeBarValue = lifeInSeconds * 10;

        Thread t = new Thread
        (delegate ()
        {
            //Initialize the progress bar
            Invoke((MethodInvoker)delegate
            {
                lifeBar.Maximum = maxLifeBarValue;
                lifeBar.Value = maxLifeBarValue;
                lifeBar.Visible = true;
                Clipboard.SetText(pd.getAccountPassword(lstAccounts.Text));
            });

            //Loop to update the progress bar
            for (int x = maxLifeBarValue; x >= 0; x--)
            {
                Thread.Sleep(100);
                Invoke((MethodInvoker)delegate
                {
                    lifeBar.Value = x;
                });
            }

            //Clear the system clipboard
            Clipboard.SetText(string.Empty);

            //Hide the progress bar when we're done
            Invoke((MethodInvoker)delegate
            {
                lifeBar.Visible = false;
            });
        });
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
    }

Это работает, но у меня проблема в том, что если пользователь запускает событие для копирования другого пароля (или того же самого; это не имеет значения), у нас теперь есть 2 потока, работающих в фоновом режиме. Это видно по тому факту, что индикатор выполнения, так сказать, «переворачивается», поскольку каждый поток обновляет свое значение независимо.

Есть ли способ, с помощью которого я могу обнаружить и прервать исходную ветку (если она существует), когда пользователь снова нажимает кнопку копирования пароля?

1 Ответ

0 голосов
/ 18 января 2019

Вы можете сохранить ссылку на поток, а затем прервать поток перед тем, как начинать новый. Как это:

private Thread passwordClearThread = null;

private void getPassword(int lifeInSeconds)
{
  int maxLifeBarValue = lifeInSeconds * 10;

  if (passwordClearThread != null && passwordClearThread.IsAlive)
  {
    passwordClearThread.Abort();
    passwordClearThread.Join();
  }

  passwordClearThread = new Thread
  (() =>
  {
    //Initialize the progress bar
    Invoke((MethodInvoker)delegate
    {
      lifeBar.Maximum = maxLifeBarValue;
      lifeBar.Value = maxLifeBarValue;
      lifeBar.Visible = true;
      Clipboard.SetText(pd.getAccountPassword(lstAccounts.Text));
    });

    //Loop to update the progress bar
    for (int x = maxLifeBarValue; x >= 0; x--)
    {
      Thread.Sleep(100);
      Invoke((MethodInvoker)delegate
      {
        lifeBar.Value = x;
      });
    }

    //Clear the system clipboard
    Clipboard.Clear();

    //Hide the progress bar when we're done
    Invoke((MethodInvoker)delegate
    {
      lifeBar.Visible = false;
    });
  });
  passwordClearThread.SetApartmentState(ApartmentState.STA);
  passwordClearThread.Start();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...