我有一个问题与我的winform应用程序在c#。在程序中,我有一个标签作为状态栏和一个这样的方法:
private void btnProcess_Click(object sender, EventArgs e)
{
lblStatus.Text = "Please wait...";
/*
Code here
*/
}
我的代码处理需要几秒钟,但在处理代码之后,标签的文本将改变,我希望它在那之前发生。
注:我是一个业余程序员,我不太懂英语,请简单地解释你的解决方案。谢谢你。
你可以通过调用Update或Refresh来使用重绘事件来破解这个问题,但真正的解决方案是使用BackgroundWorker进行更长的操作。
这不是一件容易的事情,你应该找一个你完全理解的语言的教程。
在winform应用程序(以及所有GUI应用程序)中,不建议在GUI线程中执行长任务。要解决您的问题,必须使用Thread(在这里您可以找到完整的mdsn参考)。
如果你想从另一个线程更新标签,你将做一个交叉线程操作。有关更多信息,请查看这个问题
所有代码总是在对UI进行任何更改之前运行并完成。这只是WinForms和WPF的基本逻辑。
您可以使用"BackgroundWorker",这样较长的代码将在另一个线程上运行。这样,您就可以在长代码仍在运行时自由地编辑ui元素。
如果你使用的是。net 4.5,你可以使用await
和async
而不是BackgroundWorker
。
您将创建一个async
方法返回一个任务,并在该方法中使用Task.Run()
来启动后台工作。
这里有一个例子。你会在传递给Task.Run()
的lambda中做所有缓慢的工作,我在这里评论了"在这里做所有缓慢的工作":
private async void btnProcess_Click(object sender, EventArgs e)
{
lblStatus.Text = "Please wait...";
await doSomeWorkAsynchronously();
lblStatus.Text = "Work completed";
}
private async Task doSomeWorkAsynchronously()
{
await Task.Run(()=>
{
// Do all your slow work here.
Thread.Sleep(5000); // Simulate slow work.
});
}
我认为这比使用BackgroundWorker
更容易一些。
请注意,如果你所有的"慢"方法已经async
(例如,如果你使用异步文件I/O),那么你可能只需要await
你的每个异步操作,而不必通过Task.Run()
创建你自己的任务。
你也可以从后台任务返回一个值。假设您希望返回一个字符串,以便在后台任务完成时使用该字符串更新标签。您可以这样做:
private async void btnProcess_Click(object sender, EventArgs e)
{
lblStatus.Text = "Please wait...";
lblStatus.Text = await doSomeWorkAsynchronously();
}
private async Task<string> doSomeWorkAsynchronously()
{
return await Task.Run(()=>
{
// Do all your slow work here.
Thread.Sleep(5000); // Simulate slow work.
return "The task completed.";
});
}