我有一个递归函数,并希望使用时间,尝试次数和当前递归函数的尝试来更新表单。每一秒,表格都应该更新。目前的methodinvoker不起作用。编译器将突出显示该行,但不会继续,它将弹出。
我已经尝试将该函数放在一个单独的线程上,但是它的预处理性能很差,所以我宁愿将该函数保留在主线程上。
有什么想法吗?
void bruteForce_DoWork()
{
doBruteForceEID("", 0, wordlen, temp);
}
void _myTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (InvokeRequired)
{
runTimeSec++;
this.Invoke(new MethodInvoker(delegate() { this.toolStrip.Text = "Running... " + runTimeSec + "s"; }));
Invoke(new MethodInvoker(delegate() { lblAttackA.Text = Convert.ToString(attackCount); }));
Invoke(new MethodInvoker(delegate { lblCurAttempt.Text = brute; }));
}
else
{
runTimeSec++;
toolStrip.Text = "Running... " + runTimeSec + "s";
lblAttackA.Text = Convert.ToString(attackCount);
lblCurAttempt.Text = brute;
}
}
编辑:让我解释一下程序更多...一旦用户输入了他们想要检查的密码,就会在他们点击计算后发生以下情况。 - 运行一个虚拟递归算法,看看他们的机器在5秒内可以完成多少次循环,然后我对它们进行平均,以便更好地了解它们每秒可以完成的循环次数。
back = new Thread(new ThreadStart(testLoop_DoWork)); // Calls the dummy algorithm
back.Start();
if (rbtnTest.Checked)
{
txtEID.Text = txtUID.Text;
lblRunCycle.Text = "Calculating...";
testTimer.Enabled = true; // Starts the Timer
}
一旦5秒计时器启动,我检查长度,每秒周期数,字符数(上限,下限,数字,符号),给出需要多长时间,添加相应的字符数组以创建暴力char数组,然后我加入()线程并禁用计时器。 我会得到每秒粗暴的7百万次循环...(记住这个数字)。此外,我没有在此期间更新GUI。只需运行创建的线程。
然后,如果用户想要运行攻击,它会:
attackBack = new Thread(new ThreadStart(bruteForce_DoWork));
attackBack.Start();
_myTimer.Enabled = true;
一旦我开始在新线程上运行它,它每秒只显示大约30,000个周期?我的计时器每秒只更新一次。发生了什么事?
编辑:我也只是注释了计时器,所以没有任何更新到GUI ......并且当发现蛮力时会发生相同的结果(例如,'test'这个词应该是即时的...但它需要10秒钟找到它......
答案 0 :(得分:2)
是的,这不行。 Timer.Elapsed事件在线程池线程上运行。这意味着InvokeRequired始终为true且不需要检查。什么不起作用的是Invoke()调用。它要求UI线程处于空闲状态,以便它可以执行调用的代码。
你的UI线程没有空闲,它正在执行昂贵的代码。这称为死锁。
你有以相反的方式执行此操作,让工作线程执行昂贵的代码而不是UI线程。这使得UI线程保持响应,既可以更新标签,也可以保持UI绘制并响应用户输入。你说你不喜欢这样做,目前还不清楚你为什么会遇到这个问题。一个经典的错误是经常更新UI,充斥着调用请求,因此它不再适应常规职责。定时更新确实是解决方案。永远不会每秒更新超过25次,如果你经常这样做,人眼就无法区分它。