C#、WinForms、等待计时器
C#, WinForms, waiting for timers
试图了解 C# Winforms 中的计时器和虚拟点击。我想让程序有一个用户输入的时间值 (textbox1),然后等待这段时间并单击鼠标,然后增加计数器 (textbox2)。
在下面的代码中,数字计数器立即变为 10,但点击次数永远不会结束,尽管设置了一个 while 循环以在 10 时停止点击。我基本上只是希望程序稍微随机等待一段时间(输入时间到输入时间+3),单击鼠标,增加计数器,然后选择一个新的随机数并继续,直到总共点击 10 次。
public Form1()
{
InitializeComponent();
}
private void NumbersOnly(object sender, KeyPressEventArgs e)
{
char ch = e.KeyChar;
if (!Char.IsDigit(ch) && ch != 8)
{
e.Handled = true;
}
}
static System.Timers.Timer _timer;
int numberofclicks = 0;
[DllImport("user32.dll")]
static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
private const int MOUSEEVENTF_MOVE = 0x0001;
private const int MOUSEEVENTF_LEFTDOWN = 0x0002;
private const int MOUSEEVENTF_LEFTUP = 0x0004;
private const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
private const int MOUSEEVENTF_RIGHTUP = 0x0010;
private const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
private const int MOUSEEVENTF_MIDDLEUP = 0x0040;
private const int MOUSEEVENTF_ABSOLUTE = 0x8000;
private void StartClicked(object sender, EventArgs e)
{
numberofclicks = 0;
Random rsn = new Random();
while (numberofclicks < 10)
{
string startseconds = textBox1.Text;
int timerstartseconds = Convert.ToInt32(startseconds);
int timertime = rsn.Next(timerstartseconds * 1000, ((timerstartseconds + 3) * 1000));
_timer = new System.Timers.Timer(timertime);
_timer.Elapsed += _timer_Elapsed;
_timer.Enabled = true;
textBox2.Clear();
numberofclicks++;
string numbertextbox = numberofclicks.ToString();
textBox2.Text = numbertextbox;
}
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
LeftClick();
}
public static void LeftClick()
{
mouse_event(MOUSEEVENTF_LEFTDOWN, Control.MousePosition.X, Control.MousePosition.Y, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, Control.MousePosition.X, Control.MousePosition.Y, 0, 0);
}
当您说 _timer.Enabled = true;
时,其余代码将继续执行。然后在一段时间后,当计时器滴答作响时,触发 Elapsed
事件。
此外,您创建的每个计时器都会持续计时 - 它们不会只触发一次。
此外,.NET 框架中有许多不同的 Timer 类。对于像您这样的简单 winforms 应用程序,我会坚持使用 System.Windows.Forms.Timer
版本。您不必担心线程等问题。
你可能会得到更好的服务:
private Random rsn = new Random();
private int numberofclicks = 0;
private System.Windows.Forms.Timer _timer;
// set the timer's tick event handler in form_load or similar.
// you could also just drag a timer onto the form and double-click it.
private void StartClicked(object sender, EventArgs e)
{
// don't allow starting again until finished
btnStart.Enabled = false;
numberofclicks = 0;
_timer.Interval = /* get randomish interval */
_timer.Start();
}
void _timer_Tick(object sender, EventArgs e)
{
_timer.Stop();
LeftClick();
numberofclicks++;
if (numberofclicks >= 10) {
btnStart.Enabled = true;
}
else {
_timer.Interval = /* get randomish interval */
_timer.Start();
}
}
问题在于 StartClicked
事件处理程序不会阻塞自身。这只是一个简单的方法,没有任何延迟循环 10 次更改方法级别变量和修改(甚至创建新的!)计时器属性。
有可能以这种方式(单一方法和简单循环)完成您尝试做的事情,但您将不得不使用异步事件处理程序并且不需要计时器。由于 已经讨论了如何使用经典计时器来实现,我将为您提供基于异步的解决方案:
private async void StartClicked(object sender, EventArgs e)
{
numberofclicks = 0;
Random rsn = new Random();
while (numberofclicks < 10)
{
string startseconds = textBox1.Text;
int timerstartseconds = Convert.ToInt32(startseconds);
int timertime = rsn.Next(timerstartseconds * 1000, ((timerstartseconds + 3) * 1000));
await Task.Delay(timertime);
LeftClick();
textBox2.Clear();
numberofclicks++;
string numbertextbox = numberofclicks.ToString();
textBox2.Text = numbertextbox;
}
}
有关异步等待的更多信息,您可以阅读 MSDN on async-await。
试图了解 C# Winforms 中的计时器和虚拟点击。我想让程序有一个用户输入的时间值 (textbox1),然后等待这段时间并单击鼠标,然后增加计数器 (textbox2)。
在下面的代码中,数字计数器立即变为 10,但点击次数永远不会结束,尽管设置了一个 while 循环以在 10 时停止点击。我基本上只是希望程序稍微随机等待一段时间(输入时间到输入时间+3),单击鼠标,增加计数器,然后选择一个新的随机数并继续,直到总共点击 10 次。
public Form1()
{
InitializeComponent();
}
private void NumbersOnly(object sender, KeyPressEventArgs e)
{
char ch = e.KeyChar;
if (!Char.IsDigit(ch) && ch != 8)
{
e.Handled = true;
}
}
static System.Timers.Timer _timer;
int numberofclicks = 0;
[DllImport("user32.dll")]
static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
private const int MOUSEEVENTF_MOVE = 0x0001;
private const int MOUSEEVENTF_LEFTDOWN = 0x0002;
private const int MOUSEEVENTF_LEFTUP = 0x0004;
private const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
private const int MOUSEEVENTF_RIGHTUP = 0x0010;
private const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
private const int MOUSEEVENTF_MIDDLEUP = 0x0040;
private const int MOUSEEVENTF_ABSOLUTE = 0x8000;
private void StartClicked(object sender, EventArgs e)
{
numberofclicks = 0;
Random rsn = new Random();
while (numberofclicks < 10)
{
string startseconds = textBox1.Text;
int timerstartseconds = Convert.ToInt32(startseconds);
int timertime = rsn.Next(timerstartseconds * 1000, ((timerstartseconds + 3) * 1000));
_timer = new System.Timers.Timer(timertime);
_timer.Elapsed += _timer_Elapsed;
_timer.Enabled = true;
textBox2.Clear();
numberofclicks++;
string numbertextbox = numberofclicks.ToString();
textBox2.Text = numbertextbox;
}
}
void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
LeftClick();
}
public static void LeftClick()
{
mouse_event(MOUSEEVENTF_LEFTDOWN, Control.MousePosition.X, Control.MousePosition.Y, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, Control.MousePosition.X, Control.MousePosition.Y, 0, 0);
}
当您说 _timer.Enabled = true;
时,其余代码将继续执行。然后在一段时间后,当计时器滴答作响时,触发 Elapsed
事件。
此外,您创建的每个计时器都会持续计时 - 它们不会只触发一次。
此外,.NET 框架中有许多不同的 Timer 类。对于像您这样的简单 winforms 应用程序,我会坚持使用 System.Windows.Forms.Timer
版本。您不必担心线程等问题。
你可能会得到更好的服务:
private Random rsn = new Random();
private int numberofclicks = 0;
private System.Windows.Forms.Timer _timer;
// set the timer's tick event handler in form_load or similar.
// you could also just drag a timer onto the form and double-click it.
private void StartClicked(object sender, EventArgs e)
{
// don't allow starting again until finished
btnStart.Enabled = false;
numberofclicks = 0;
_timer.Interval = /* get randomish interval */
_timer.Start();
}
void _timer_Tick(object sender, EventArgs e)
{
_timer.Stop();
LeftClick();
numberofclicks++;
if (numberofclicks >= 10) {
btnStart.Enabled = true;
}
else {
_timer.Interval = /* get randomish interval */
_timer.Start();
}
}
问题在于 StartClicked
事件处理程序不会阻塞自身。这只是一个简单的方法,没有任何延迟循环 10 次更改方法级别变量和修改(甚至创建新的!)计时器属性。
有可能以这种方式(单一方法和简单循环)完成您尝试做的事情,但您将不得不使用异步事件处理程序并且不需要计时器。由于
private async void StartClicked(object sender, EventArgs e)
{
numberofclicks = 0;
Random rsn = new Random();
while (numberofclicks < 10)
{
string startseconds = textBox1.Text;
int timerstartseconds = Convert.ToInt32(startseconds);
int timertime = rsn.Next(timerstartseconds * 1000, ((timerstartseconds + 3) * 1000));
await Task.Delay(timertime);
LeftClick();
textBox2.Clear();
numberofclicks++;
string numbertextbox = numberofclicks.ToString();
textBox2.Text = numbertextbox;
}
}
有关异步等待的更多信息,您可以阅读 MSDN on async-await。