Timed UI Updates in Compact Framework

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi,
I have an application running on a PocketPC written in
C#. The app collects information from the user and also
does database connections periodically with a seperate
background thread. I'm hoping to display the status of
this background thread
(IE: "Connecting", "Downloading", "Disconnected") to the
user via a statusBar.

To keep the background thread and user-interface threads
seperate, I have a 'Status' property in the background
thread that I would like the UI to occasionally check.

To try it out, I created a System.Threading.Timer in the
UI (Form1) thread and had it run an 'Update' function
that changes the statusBar.Text property to the current
time. Unfortunately, this seemed to partially freeze the
application. I put a MessageBox before the
statusbar.text update and found that the function
continues to be called but the thread stops when it hits
the statusBar property.

I tried the same code in a non pocketPC environment (just
a regular C# application for winxp) and it works fine.

I was wondering what's up with the PocketPC UI threading
that would make it behave this way.

Any help much appreciated.
 
Here's the general code I'm referring to for the simple
statusbar time update example...

public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.StatusBar statusBar1;
private System.Threading.Timer statusTimer;

public Form1()
{
InitializeComponent();

statusTimer = new System.Threading.Timer(new
System.Threading.TimerCallback(StatusUpdate), null, 0,
15000);
}

private void StatusUpdate(object pass)
{
MessageBox.Show("Show This");
statusBar1.Text = DateTime.Now.ToString() + "*";
}
}

If you run something like this on a pocketpc you'll
get "Show This" boxes but after you click the first one
(or so) the status bar stops changing...

Thanks for the help...
 
You are modifying a property of the UI outside the main thread, and this is
bad (I think it's just a case that it works on a non pocket pc environment).
You should invoke it through the Invoke method provided by the Form class.

Here is the right code

private void StatusUpdate(object pass)
{
this.Invoke(new Delegate(this.StatusUpdateUIThread));
}

private void StatusUpdateUIThread()
{
statusBar1.Text = DateTime.Now.ToString() + "*";
}

GV
 
Thanks for the tip and comments on the UI. I knew about
the general UI guidelines for not updating controls
through a second thread but was a little confused by the
Timer threads and then how it worked in regular WinXP.
Good to know about the Invoke method.

BUT, I'm still having a problem. I tried your code
change, except I added:

the public member
and changed the Invoke line to:instead of 'new Delegate' since I got compilation errors
the other way.

With these changes I am still running into problems,
though. When the invoke method is called I get 'a
Managed ArgumentException' error that stops the program.
I'm not too familiar with using Invoke so perhaps someone
could let me know where I'm off. With windows XP I
solved the problem by putting the initial timer creation
code in the Form_Load event instead of the form
constructor (I got an error telling me that the window
did not yet have a handle created).

With PocketPC I only get that managed ArgumentException
error. It is related to the use of the Invoke/delegate
and not the statusbar property (it still gives an error
if I comment out the statusbar.text line.

Thanks again for all the help!

- Z
 
AHA. I finally found the answer!

On PocketPCs you can't create custom delegates,
apparently. I found this little tidbit:
http://msdn.microsoft.com/mobility/prodtechinfo/devtools/n
etcf/FAQ/#7.10

So, instead of a 'new Delegate' or 'new MyMethod' I had
to make a 'new EventHandler'. Now it seems to be working.

Hope this doesn't cause everyone else as much wasted time
as it did me.

have a good one,
- Z
 
Back
Top