2011-07-09 39 views
2

我似乎有正确的顺序执行命令的问题,我在我的程序的方法:C#方法,说明以正确的顺序不执行

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被锁定,因为程序是单线程的。

我试过线程更早,但对我的生活我不能得到正确的语法,我想:

Thread MyThread = new Thread(LongClass.LongFunction); 

Thread MyThread = new Thread(new ThreadStart(LongClass.LongFunction)); 

哪里LongClass是包含LongFunction作为一个静态方法的类。 我会检查出现在的背景工作者。

+0

如果您在'LongMethod()'之前向'Application.DoEvents()'添加了一个调用,那么您将使用临时创可解决此问题。杰森的回答是正确的方法。 –

回答

6

您应该在另一个线程上执行LongMethod,以便UI线程在运行时不会阻塞。

+0

LongMethod是另一个类的静态方法,我还可以在另一个线程上运行它吗? – 7VoltCrayon

+0

@Suleman是的。通常,任何长时间运行的进程都不应该阻塞UI线程。相反,您可以让LongMethod在另一个线程上运行;然后提出一个事件来通知UI它已完成。 – vcsjones

+1

'BackgroundWorker'使这个更容易一些。 –

3

虽然我认为Jason的使用另一个线程的答案是要走的路,但还有另一个“evil”选项。

Statuslabel.Text = "Working..."; 

Application.DoEvents(); 

LongMethod(); 

Statuslabel.Text = "Done"; 
6

记住,更新UI是运行的代码就像其他任何东西。当您的长时间运行的方法正在运行时,该线程没有执行重绘用户界面所需的任何任务。更改UI元素并不会阻止所有内容并重新绘制它,因为假设您更改了一千个UI元素;你不会期望在每一个之后重绘;在你做出所有改变之后,你会希望他们都会立即发生。长话短说,如果你想刷新更新后的用户界面,但在长时间运行的代码之前 - 也就是说,你不关心挂用户界面,但你至少希望它更新 - 然后插入一个明确刷新UI的调用。

有些人建议将“DoEvents”作为解决方法。这可以工作,但它是超级危险。有两个原因。首先,假设用户点击一次按钮两次。在第一次点击的处理过程中,你做了一个DoEvents,然后你递归嘿,现在你已经暂停了第一个按钮点击的处理,以便你可以处理第二个按钮的点击......并且可以'不错。其次,假设你正在处理一个事件,并且你做了一个DoEvents,它使你开始处理另一个事件,然后当你这样做时,你做了一个DoEvents,并且这会导致你开始处理第三个事件...并且这一直持续下去。你什么时候完成第一个事件?潜在的从来没有。记住“DoEvents”基本上意思是“专注于刚刚发生的事情,牺牲了你已经在做的事情”。

+0

对于事实+1:DoEvents。我花了数周的时间修复由认为DoEvents是神奇的治疗方法的人编写的代码 - 这意味着他永远不必费心研究线程是如何工作的。 (为了记录,有人不是我);)) –