当我做长时间运行的任务时,我想显示忙碌的图像并在完成工作时隐藏忙碌的图像。
private void btnSave_Click(object sender, EventArgs e)
{
string strRating = "";
Messages oErrMsg = Messages.Instance;
FeedBack oFeedBack = new FeedBack();
picbox.Visible = true;
Application.DoEvents();
if (cboRating.Text.Trim() == "--Select--")
{
strRating = "";
}
else
{
strRating = cboRating.Text.Trim();
}
try
{
oErrMsg = oFeedBack.UpdateFeedBack(JobID, strRating, txtComments.Text.Trim(), AccountRef, PartNumber);
if (!oErrMsg.IsError)
{
picbox.Visible = false;
comments _cmm = new comments();
_cmm.Comments = txtComments.Text;
_cmm.Rating = strRating;
_cmm.Row = this.Row;
_cmm.Col = this.Col;
OnValueChanged(_cmm);
DialogResult = DialogResult.OK;
this.Close();
}
else
{
picbox.Visible = false;
MessageBox.Show(oErrMsg.Message);
}
}
catch (Exception ex)
{
picbox.Visible = false;
MessageBox.Show(ex.Message.ToString());
}
}
picbox.Visible = true;
picbox有忙图像,但问题是图像没有显示,因为我显示忙,然后长时间运行操作开始。所以指导我如何异步显示繁忙的图像并在完成工作时隐藏。感谢
答案 0 :(得分:1)
托马斯,
请考虑使用BackgroundWorker(http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.80).aspx)。
自2.0版以来,它一直存在于.NET框架中。
答案 1 :(得分:1)
正如@Piotr所建议的那样,您可以使用BackgroundWorker线程来实现这一目标。
作为你的代码无法工作的原因,btn点击处理程序在UI线程上运行,你碰巧在同一个(UI)线程中完成所有工作,这意味着UI线程无法在Busy中绘制更改指示器。
虽然Application.DoEvents()有助于强制重绘,但应该避免它,并且正确的方法是将所有工作委托给后台线程(您也可以使用ThreadPool.QueueUserWorkItem)并封送所有对UI对象的更改使用Control.BeginInvoke / Control.Invoke。
将属性添加到UI线程因为,UI对象的任何更改只能在UI线程上完成,您必须使用Control.Invoke等来封送此类更新。
BackgrounWorker类通过提供不同的事件处理程序来封装此编组。从内存中,我精简了ProgressChanged和Completed处理程序在UI线程上调用。因此,您可以安全地更新这些处理程序中的UI控件,并在DoWork处理程序中执行耗时的工作。
更新:以下是DoEvents is Evil。
的原因