Question

when i am doing long running task then i want to show busy image and hide the busy image when job done.

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 has busy image but the problem is image is not showing because i am show busy and then a long running operation start. so guide me how could i show the busy image asynchronously and hide when job done. thanks

Was it helpful?

Solution

As suggested by @Piotr, you can make use of BackgroundWorker thread to achieve this.

As a reasoning why your code is not working, the btn click handler runs on UI thread and you happen to be doing all the work in the same (UI) thread which mean UI thread doesn't get to paint changes in Busy Indicator.

while Application.DoEvents() helps in a force repaint, it should be avoided and the right way to achieve this is delegating all work to a background thread (you can also use ThreadPool.QueueUserWorkItem) and marshal all changes to UI object/properties to UI thread by using Control.BeginInvoke/Control.Invoke.

Since, any changes to a UI object could only be done on a UI thread you will have to marshal such updates by using Control.Invoke etc.

BackgrounWorker class encapsulates this marshalling by providing differenet event handlers. From memory, I thin ProgressChanged and Completed handlers are invoke on UI thread. So you can safely update your UI control within these handlers and do the time consuming work in DoWork handler.

Update: Here is good explanation on why DoEvents is Evil.

OTHER TIPS

Thomas,

please consider using a BackgroundWorker (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.80).aspx).

It's been present in the .NET framework since the version 2.0.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top