我正在研究一个实现密码管理器的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个线程在后台运行。事实证明,进度条正在“翻转”,可以说是每个线程都在独立更新其值。
当用户再次单击“复制密码”按钮时,是否可以检测并终止原始线程(如果存在)?
答案 0 :(得分:1)
您可以保留对该线程的引用,然后在启动新线程之前中止该线程。像这样:
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();
}