我似乎在按正确顺序执行命令时遇到问题,我的程序中有一个方法:
private void GenerateButton_Click(object sender, EventArgs e)
{
Statuslabel.Text = "Working...";
LongMethod();
//Call to another Method of another class which takes 15-20 seconds to execute
Statuslabel.Text = "Done";
}
问题似乎是,不是将“工作”分配给状态标签,然后调用LongMethod
,程序似乎首先执行LongMethod()
,然后将状态标签的文本更改为“工作“一瞬间,然后立即将其更改为”完成“。
哦,在LongMethod()
执行期间UI被锁定,因为程序是SingleThreaded。
我之前尝试过线程,但是对于我的生活,我无法正确理解语法,我试过了:
Thread MyThread = new Thread(LongClass.LongFunction);
Thread MyThread = new Thread(new ThreadStart(LongClass.LongFunction));
其中LongClass
是包含LongFunction
作为静态方法的类。
我现在将检查后台工作人员。
答案 0 :(得分:6)
您应该在另一个线程上执行LongMethod
,以便UI线程在运行时不会阻塞。
答案 1 :(得分:6)
请记住,更新UI是运行代码,就像其他任何东西一样。当您的长时间运行方法正在运行时,该线程不会执行重绘用户界面所需的任何任务。更改UI元素不会停止所有内容并重新绘制它,因为假设您更改了一千个UI元素;你不会期望在每一个之后重绘;在你做出所有改变之后,你会发现它们都会立即发生。
简而言之,如果您想在更新后但在长时间运行的代码之前刷新UI - 也就是说,您不关心挂起UI但至少希望它更新 - 那么< em>插入一个显式刷新UI的调用。
有些人建议将“DoEvents”作为解决方法。这可以工作,但它是超级危险的。有两个原因。首先,假设用户点击两次按钮。在第一次单击处理期间,您执行DoEvents,然后递归,然后,现在您已暂停第一次按钮单击的处理,以便您可以处理第二个按钮单击。那不可能是好事。
其次,假设您正在处理一个事件,并且您执行DoEvents,这会导致您开始处理另一个事件,然后在您执行此操作时,您执行DoEvents,这会导致您开始处理第三个事件......这一直在继续。你什么时候完成第一次活动的处理?可能从不。记住“DoEvents”基本上意味着“专注于刚刚发生的事情而牺牲你已经在做的事情。”
答案 2 :(得分:3)
虽然我认为Jason使用另一个线程的答案是要走的路,但还有另一个“evil”选项。
Statuslabel.Text = "Working...";
Application.DoEvents();
LongMethod();
Statuslabel.Text = "Done";