0 Replies - 3845 Views - Last Post: 14 March 2013 - 03:39 AM

#1 maj3091  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 300
  • View blog
  • Posts: 1,776
  • Joined: 26-March 09

.NetCF V2 Thread not "responding" intermittently

Posted 14 March 2013 - 03:39 AM

Hi,

I'm having a strange issue with a mobile app on WinCE 5 (C# and .NetCF V2), whereby a User Control (custom progressbar), doesn't respond to a request to stop.

Unfortunately, I'm unable to produce the issue myself, but a customer says it's happening all the time (same device, same OS, etc.).

The user control was written for us a while back and it's basically a form that fills the screen transparently, then draws the progress bar itself (no controls used). It updates the progress on a timer (very basic, just a cycling bar).

It is created on a thread, so that background comms can continue.

The code for creating and controlling the control is as follows:

   public class ProgressBarCtrl
    {
        private frmProgress progress = null;
        private string sMsg;
        private int v;
        private int mn;
        private int mx;
        private int MaxWaitTime = 0;

        public ProgressBarCtrl(string sMessage, int value, int min, int max, int maxwait)
        {
            try
            {
                sMsg = sMessage;
                v = value;
                mn = min;
                mx = max;
                MaxWaitTime = maxwait;

                // Create a new thread from which to start the progress bar form
                Thread progressBarThread = new Thread(new ThreadStart(StartProgressBar));
                progressBarThread.Start();
            }
            catch
            {
                //what to do? rethrow a new exception?
            }
        }

        private void StartProgressBar()
        {
            try
            {
                progress = new frmProgress(sMsg, v, mn, mx, MaxWaitTime);
                Application.Run(progress);
            }
            catch
            {
                //what to do? rethrow a new exception?
            }
        }

        public void StopProgressBar()
        {
            try
            {
                if (progress != null)
                {
                    progress.Invoke(new EventHandler(progress.Stop));
                    progress.Dispose();
                    progress = null;
                }
            }
            catch
            {
                //what to do? rethrow a new exception?
            }
        }
    }




The basic outline of the code for the control itself, as as follows:

    class frmProgress : Form
    {

        private System.Windows.Forms.Timer timer;

        int MARGIN = 5;
        int incrementProgress = 1;
        int curProgress = 0;
        long lngTotalProgressTime = 0;
        int minProgress = 0;
        int maxProgress = 1000;
        int maxWait = 2200;
        String txtMessage = "Please Wait...";

        Graphics g = null;
        Rectangle rBox = new Rectangle();
        Rectangle rCaption = new Rectangle();
        Rectangle rCaptionText = new Rectangle();
        Rectangle rProgress = new Rectangle();
        Rectangle rMessage = new Rectangle();
        Font fCaption;
        Font fMessage;

        public frmProgress()
        {
        }

        public frmProgress(string sMessage, int value, int min, int max, int maxW)
        {
            try
            {
                txtMessage = sMessage;
                incrementProgress = value;
                minProgress = min;
                maxProgress = max;
                curProgress = min;
                maxWait = maxW;
                lngTotalProgressTime = 0;

                this.timer = new System.Windows.Forms.Timer();
                this.timer.Interval = 500;  //new 07012008 - was 100
                this.timer.Tick += new System.EventHandler(this.timer_Tick);

                this.MinimizeBox = false;
                this.WindowState = FormWindowState.Maximized;
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
                this.Load += new System.EventHandler(this.frmProgress_Load);
            }
            catch
            {
                //what to do? rethrow a new exception?
            }
        }
     
        void onmousedown(object sender, MouseEventArgs e)
        {
        }

        private void Draw(Boolean bAll)
        {
            try
            {
                if (g == null)
                    return;

                if (bAll)
                {
                    g.FillRectangle(new SolidBrush(SystemColors.Window), rBox);
                    g.FillRectangle(new SolidBrush(SystemColors.ActiveCaption), rCaption);
                    ..... etc, etc. (full Drawing code removed to make it more readable)

                    SolidBrush(SystemColors.ActiveCaptionText), rCaptionText);
                    g.DrawString(txtMessage, fMessage, new SolidBrush(SystemColors.WindowText),    rMessage);
                    g.FillRectangle(new SolidBrush(Color.White), rProgress);
                }
                else
                {
                    Rectangle rCurProgress = new Rectangle();
                    Rectangle rRemainingProgress = new Rectangle();
                    
..... etc, etc. (full Drawing code removed to make it more readable)

                    g.FillRectangle(new SolidBrush(SystemColors.ScrollBar), rCurProgress);
                    g.FillRectangle(new SolidBrush(Color.White), rRemainingProgress);
                }
            }
            catch
            {
                //what to do? rethrow a new exception?
            }
        }

        private void frmProgress_Load(object sender, EventArgs e)
        {
            try
            {
                int screenHeight = Screen.PrimaryScreen.Bounds.Height;
                int screenWidth = Screen.PrimaryScreen.Bounds.Width;

                int pbWidth = screenWidth * 2 / 3;
                int pbHeight = 0;

                g = this.CreateGraphics();

                fCaption = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
                rCaptionText.Size = g.MeasureString("Please wait...", fCaption).ToSize();
                rCaptionText.Size = new Size(pbWidth - 2 * MARGIN, rCaptionText.Size.Height);

                rCaption.Size = new Size(pbWidth, rCaptionText.Size.Height);
                pbHeight += rCaption.Height + MARGIN;

                rProgress.Width = pbWidth - (2 * MARGIN);
                rProgress.Height = 20;
                pbHeight += rProgress.Height + MARGIN;

                fMessage = new Font(FontFamily.GenericSansSerif, 8, FontStyle.Regular);
                Size messageSize = g.MeasureString(txtMessage, fMessage).ToSize();

                if (messageSize.Width > pbWidth - (2 * MARGIN))
                {
                    int numLines = (messageSize.Width / (pbWidth - (2 * MARGIN))) + 1;

                    messageSize.Width = pbWidth - (2 * MARGIN);
                    messageSize.Height *= numLines;
                }

                rMessage.Size = messageSize;
                pbHeight += rMessage.Height + MARGIN;

                rBox.Size = new System.Drawing.Size(pbWidth, pbHeight < screenHeight ? pbHeight : screenHeight);
                rBox.Location = new Point((screenWidth - rBox.Width) / 2, (screenHeight - rBox.Height) / 2);
                rCaptionText.Location = new Point(rBox.Left + MARGIN, rBox.Top);
                rCaption.Location = new Point(rBox.Left , rBox.Top);
                rProgress.Location = new Point(rBox.Left + MARGIN, rCaption.Bottom + MARGIN);
                rMessage.Location = new Point(rBox.Left + MARGIN, rProgress.Bottom + MARGIN);

                Draw(true);

                this.Show();
                this.TopMost = true;
                timer.Enabled = true;
            }
            catch
            {
                //what to do? rethrow a new exception?
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Draw(true);
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
        }

        public void Stop( object o, EventArgs e)
        {
            this.Close();
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            try
            {
                curProgress += incrementProgress;
                lngTotalProgressTime += incrementProgress;

                if (lngTotalProgressTime < maxWait)
                {
                    if (curProgress > maxProgress)
                        curProgress = minProgress;

                    Draw(false);

                }
                else
                {
                    lngTotalProgressTime = 0;
                    this.Close();
                }

            }
            catch
            {
                //what to do? rethrow a new exception?
            }
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
            this.AutoScroll = true;
            this.ClientSize = new System.Drawing.Size(638, 455);
            this.Name = "frmProgress";
            this.Text = "PROGRESS";
            this.ResumeLayout(false);

        }
    }




The code is called from another form using the two methods as follows:

        ProgressBarCtrl Progress;
        int mintStep = 0;

        private void ShowProgressBar(string strText, int intMaxWait)
        {
            try
            {
                Progress = new ProgressBarCtrl(strText, 10, 0, 100, intMaxWait);
            }
            catch { }
        }

        private void HideProgressBar()
        {
            try
            {
                Progress.StopProgressBar();
            }
            catch { }
        }



So, during normal use, when a long operation is to take place, then we would call ShowProgressBar (which has a timeout) and we would call HideProgressBar when the operation was complete.

In certain circumstances, we may do this a couple of times in a row.

The problem at the customer site, is that he is saying the progressbar stays on screen, for the timeout period, but in debug logs, I can see that HideProgressBar is being called.

So my questions are as follows:

1. Is there any particular reason that the Stop method would be ignored?

2. Is the code in the control to Stop the thread adequate enough to ensure that the thread is ended completely?


Any pointers would be greatly appreciated.

Is This A Good Question/Topic? 0
  • +

Page 1 of 1