By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,144 Members | 872 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,144 IT Pros & Developers. It's quick & easy.

App sporadically hangs while raising event while processing system.threading.timer event

P: n/a
Dan
I've created a pocketpc app which has a startup form containing a listview.
The form creates an object which in turn creates a System.Threading.Timer.
It keeps track of the Timer state using a TimerState object similar to the
example in the System.Threading.Timer documentation. The method which
handles the timer events, among other things, periodically calls a method in
this TimerState object which raises an event to the startup form, which in
turn adds a record to the listview. Sporadically this code in the startup
form hangs when it tries to add the record to the listview:

listView1.Items.Add(lvi).

I first noticed this happening when I happend to dock the iPAQ while it was
adding an item. The ActiveSync messagebox came up and hung, as did my
process. I am now able to reproduce it at will by adding a MessageBox call
prior to raising the event. The messagebox call returns but the messagebox
itself remains displayed on the screen, and my process hangs at the line
mentioned above.

Anyone have any thoughts on what's going on? The details of the
implementation are described below....Dan

1. Form1 creates an UploadLooper object.

2. UploadLooper creates a TimerState object, similar to the example in
the System.Threading.Timer documentation.

3. The UploadLooper module also contains a delegate declaration, along
with a declaration for an UploadEvent object derived from EventArgs:

public delegate void StatusEvent(Object sender, UploadEvent e);

4. The TimerState object declares the event and contains a RaiseStatus
method which enables us to fire StatusEvent:

public class TimerState

{

public event StatusEvent StatusMessage; // Declaration of the event

....

public void RaiseStatus(string message)

{

Tracer.WriteLine("TimerState.RaiseStatus", "Before raising event");

if (StatusMessage != null)

StatusMessage(this, new UploadEvent(message));

Tracer.WriteLine("TimerState.RaiseStatus", "After raising event");

}

5. The TimerState object also contains a Timer property itself, which
references the Timer we are going to create. We start the timer via the
UploadLooper.StartTimer method as follows:

public void StartTimer(uint millisecondInterval)

{

// Create the delegate that handles the timer events

System.Threading.TimerCallback timerDelegate = new
TimerCallback(CheckStatus);

// Create a timer that waits one second, then invokes every
'millisecondInterval' milliseconds

// and give TimerState a reference to the timer so we can dispose it when
necessary

m_TimerState.TimerInterval = millisecondInterval;

m_TimerState.Timer = new System.Threading.Timer(timerDelegate, m_TimerState,
(uint) 5000, millisecondInterval);

}

6. The CheckStatus method gets called when the Timer fires, and casts
the object it receives to a TimerState object:

static void CheckStatus(Object state)

{

TimerState timerState = (TimerState) state;

timerState.Timer.Change(Timeout.Infinite, Timeout.Infinite); // Disable the
timer

7. CheckStatus then goes on to do its processing. Periodically, calls
the TimerState.RaiseStatus method, which raises an event. Form1 catches the
event and adds a ListViewItem to a ListView:

private void AddNewStatus(string message)

{

Tracer.WriteLine("Form1.AddNewStatus", "Entering sub. Message: " + message);

ListViewItem lvi = new ListViewItem(DateTime.Now.ToString("hh:mm:ss"));

Tracer.WriteLine("Form1.AddNewStatus", "After creating lvi");

lvi.SubItems.Add(message);

Tracer.WriteLine("Form1.AddNewStatus", "After adding subitem");

listView1.Items.Add(lvi);

Tracer.WriteLine("Form1.AddNewStatus", "After adding lvi to listView");

listView1.Refresh();

Tracer.WriteLine("Form1.AddNewStatus", "Exiting sub.");

}

8. Sporadically, the AddNewStatus method hangs on
listView1.Items.Add(lvi). I first noticed this happening when I happend to
dock the iPAQ while it was adding an item. The ActiveSync messagebox came
up and hung, as did my process. I am now able to reproduce it at will by
adding a MessageBox call prior to raising an event. The messagebox call
returns but the messagebox itself remains displayed on the screen, and my
process hangs at the line mentioned above.


Nov 16 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Well... and now for the hundred's time... You're trying to update the UI
thread from a different (Timer's) thread. You MUST use Control.Invoke in
order to do that.

--
Alex Yakhnin, .NET CF MVP
www.intelliprog.com
www.opennetcf.org

"Dan" wrote:
I've created a pocketpc app which has a startup form containing a listview.
The form creates an object which in turn creates a System.Threading.Timer.
It keeps track of the Timer state using a TimerState object similar to the
example in the System.Threading.Timer documentation. The method which
handles the timer events, among other things, periodically calls a method in
this TimerState object which raises an event to the startup form, which in
turn adds a record to the listview. Sporadically this code in the startup
form hangs when it tries to add the record to the listview:

listView1.Items.Add(lvi).

I first noticed this happening when I happend to dock the iPAQ while it was
adding an item. The ActiveSync messagebox came up and hung, as did my
process. I am now able to reproduce it at will by adding a MessageBox call
prior to raising the event. The messagebox call returns but the messagebox
itself remains displayed on the screen, and my process hangs at the line
mentioned above.

Anyone have any thoughts on what's going on? The details of the
implementation are described below....Dan

1. Form1 creates an UploadLooper object.

2. UploadLooper creates a TimerState object, similar to the example in
the System.Threading.Timer documentation.

3. The UploadLooper module also contains a delegate declaration, along
with a declaration for an UploadEvent object derived from EventArgs:

public delegate void StatusEvent(Object sender, UploadEvent e);

4. The TimerState object declares the event and contains a RaiseStatus
method which enables us to fire StatusEvent:

public class TimerState

{

public event StatusEvent StatusMessage; // Declaration of the event

....

public void RaiseStatus(string message)

{

Tracer.WriteLine("TimerState.RaiseStatus", "Before raising event");

if (StatusMessage != null)

StatusMessage(this, new UploadEvent(message));

Tracer.WriteLine("TimerState.RaiseStatus", "After raising event");

}

5. The TimerState object also contains a Timer property itself, which
references the Timer we are going to create. We start the timer via the
UploadLooper.StartTimer method as follows:

public void StartTimer(uint millisecondInterval)

{

// Create the delegate that handles the timer events

System.Threading.TimerCallback timerDelegate = new
TimerCallback(CheckStatus);

// Create a timer that waits one second, then invokes every
'millisecondInterval' milliseconds

// and give TimerState a reference to the timer so we can dispose it when
necessary

m_TimerState.TimerInterval = millisecondInterval;

m_TimerState.Timer = new System.Threading.Timer(timerDelegate, m_TimerState,
(uint) 5000, millisecondInterval);

}

6. The CheckStatus method gets called when the Timer fires, and casts
the object it receives to a TimerState object:

static void CheckStatus(Object state)

{

TimerState timerState = (TimerState) state;

timerState.Timer.Change(Timeout.Infinite, Timeout.Infinite); // Disable the
timer

7. CheckStatus then goes on to do its processing. Periodically, calls
the TimerState.RaiseStatus method, which raises an event. Form1 catches the
event and adds a ListViewItem to a ListView:

private void AddNewStatus(string message)

{

Tracer.WriteLine("Form1.AddNewStatus", "Entering sub. Message: " + message);

ListViewItem lvi = new ListViewItem(DateTime.Now.ToString("hh:mm:ss"));

Tracer.WriteLine("Form1.AddNewStatus", "After creating lvi");

lvi.SubItems.Add(message);

Tracer.WriteLine("Form1.AddNewStatus", "After adding subitem");

listView1.Items.Add(lvi);

Tracer.WriteLine("Form1.AddNewStatus", "After adding lvi to listView");

listView1.Refresh();

Tracer.WriteLine("Form1.AddNewStatus", "Exiting sub.");

}

8. Sporadically, the AddNewStatus method hangs on
listView1.Items.Add(lvi). I first noticed this happening when I happend to
dock the iPAQ while it was adding an item. The ActiveSync messagebox came
up and hung, as did my process. I am now able to reproduce it at will by
adding a MessageBox call prior to raising an event. The messagebox call
returns but the messagebox itself remains displayed on the screen, and my
process hangs at the line mentioned above.


Nov 16 '05 #2

P: n/a
You cannot affect the UI from a worker thread, which the Thread.Timer is.
You *must* use Invoke to marshal calls to the UI.

<ctacke/>
www.opennetcf.org
"Dan" <da*@dontspamme.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
I've created a pocketpc app which has a startup form containing a listview. The form creates an object which in turn creates a System.Threading.Timer.
It keeps track of the Timer state using a TimerState object similar to the
example in the System.Threading.Timer documentation. The method which
handles the timer events, among other things, periodically calls a method in this TimerState object which raises an event to the startup form, which in
turn adds a record to the listview. Sporadically this code in the startup
form hangs when it tries to add the record to the listview:

listView1.Items.Add(lvi).

I first noticed this happening when I happend to dock the iPAQ while it was adding an item. The ActiveSync messagebox came up and hung, as did my
process. I am now able to reproduce it at will by adding a MessageBox call prior to raising the event. The messagebox call returns but the messagebox itself remains displayed on the screen, and my process hangs at the line
mentioned above.

Anyone have any thoughts on what's going on? The details of the
implementation are described below....Dan

1. Form1 creates an UploadLooper object.

2. UploadLooper creates a TimerState object, similar to the example in the System.Threading.Timer documentation.

3. The UploadLooper module also contains a delegate declaration, along with a declaration for an UploadEvent object derived from EventArgs:

public delegate void StatusEvent(Object sender, UploadEvent e);

4. The TimerState object declares the event and contains a RaiseStatus method which enables us to fire StatusEvent:

public class TimerState

{

public event StatusEvent StatusMessage; // Declaration of the event

...

public void RaiseStatus(string message)

{

Tracer.WriteLine("TimerState.RaiseStatus", "Before raising event");

if (StatusMessage != null)

StatusMessage(this, new UploadEvent(message));

Tracer.WriteLine("TimerState.RaiseStatus", "After raising event");

}

5. The TimerState object also contains a Timer property itself, which
references the Timer we are going to create. We start the timer via the
UploadLooper.StartTimer method as follows:

public void StartTimer(uint millisecondInterval)

{

// Create the delegate that handles the timer events

System.Threading.TimerCallback timerDelegate = new
TimerCallback(CheckStatus);

// Create a timer that waits one second, then invokes every
'millisecondInterval' milliseconds

// and give TimerState a reference to the timer so we can dispose it when
necessary

m_TimerState.TimerInterval = millisecondInterval;

m_TimerState.Timer = new System.Threading.Timer(timerDelegate, m_TimerState, (uint) 5000, millisecondInterval);

}

6. The CheckStatus method gets called when the Timer fires, and casts
the object it receives to a TimerState object:

static void CheckStatus(Object state)

{

TimerState timerState = (TimerState) state;

timerState.Timer.Change(Timeout.Infinite, Timeout.Infinite); // Disable the timer

7. CheckStatus then goes on to do its processing. Periodically, calls the TimerState.RaiseStatus method, which raises an event. Form1 catches the event and adds a ListViewItem to a ListView:

private void AddNewStatus(string message)

{

Tracer.WriteLine("Form1.AddNewStatus", "Entering sub. Message: " + message);
ListViewItem lvi = new ListViewItem(DateTime.Now.ToString("hh:mm:ss"));

Tracer.WriteLine("Form1.AddNewStatus", "After creating lvi");

lvi.SubItems.Add(message);

Tracer.WriteLine("Form1.AddNewStatus", "After adding subitem");

listView1.Items.Add(lvi);

Tracer.WriteLine("Form1.AddNewStatus", "After adding lvi to listView");

listView1.Refresh();

Tracer.WriteLine("Form1.AddNewStatus", "Exiting sub.");

}

8. Sporadically, the AddNewStatus method hangs on
listView1.Items.Add(lvi). I first noticed this happening when I happend to dock the iPAQ while it was adding an item. The ActiveSync messagebox came
up and hung, as did my process. I am now able to reproduce it at will by
adding a MessageBox call prior to raising an event. The messagebox call
returns but the messagebox itself remains displayed on the screen, and my
process hangs at the line mentioned above.


Nov 16 '05 #3

P: n/a
Dan
If that is true, then why does this code *ever* work? (It almost always
does).

Also-- can you point me to a good article on Invoke? Thanks very much...Dan

"Chris Tacke, eMVP" <ct****@spamfree-opennetcf.org> wrote in message
news:uH**************@TK2MSFTNGP15.phx.gbl...
You cannot affect the UI from a worker thread, which the Thread.Timer is.
You *must* use Invoke to marshal calls to the UI.

<ctacke/>
www.opennetcf.org
"Dan" <da*@dontspamme.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
I've created a pocketpc app which has a startup form containing a listview.
The form creates an object which in turn creates a System.Threading.Timer. It keeps track of the Timer state using a TimerState object similar to the example in the System.Threading.Timer documentation. The method which
handles the timer events, among other things, periodically calls a method in
this TimerState object which raises an event to the startup form, which

in turn adds a record to the listview. Sporadically this code in the startup form hangs when it tries to add the record to the listview:

listView1.Items.Add(lvi).

I first noticed this happening when I happend to dock the iPAQ while it

was
adding an item. The ActiveSync messagebox came up and hung, as did my
process. I am now able to reproduce it at will by adding a MessageBox

call
prior to raising the event. The messagebox call returns but the

messagebox
itself remains displayed on the screen, and my process hangs at the line
mentioned above.

Anyone have any thoughts on what's going on? The details of the
implementation are described below....Dan

1. Form1 creates an UploadLooper object.

2. UploadLooper creates a TimerState object, similar to the example

in
the System.Threading.Timer documentation.

3. The UploadLooper module also contains a delegate declaration,

along
with a declaration for an UploadEvent object derived from EventArgs:

public delegate void StatusEvent(Object sender, UploadEvent e);

4. The TimerState object declares the event and contains a

RaiseStatus
method which enables us to fire StatusEvent:

public class TimerState

{

public event StatusEvent StatusMessage; // Declaration of the event

...

public void RaiseStatus(string message)

{

Tracer.WriteLine("TimerState.RaiseStatus", "Before raising event");

if (StatusMessage != null)

StatusMessage(this, new UploadEvent(message));

Tracer.WriteLine("TimerState.RaiseStatus", "After raising event");

}

5. The TimerState object also contains a Timer property itself, which references the Timer we are going to create. We start the timer via the
UploadLooper.StartTimer method as follows:

public void StartTimer(uint millisecondInterval)

{

// Create the delegate that handles the timer events

System.Threading.TimerCallback timerDelegate = new
TimerCallback(CheckStatus);

// Create a timer that waits one second, then invokes every
'millisecondInterval' milliseconds

// and give TimerState a reference to the timer so we can dispose it when necessary

m_TimerState.TimerInterval = millisecondInterval;

m_TimerState.Timer = new System.Threading.Timer(timerDelegate,

m_TimerState,
(uint) 5000, millisecondInterval);

}

6. The CheckStatus method gets called when the Timer fires, and casts the object it receives to a TimerState object:

static void CheckStatus(Object state)

{

TimerState timerState = (TimerState) state;

timerState.Timer.Change(Timeout.Infinite, Timeout.Infinite); // Disable

the
timer

7. CheckStatus then goes on to do its processing. Periodically,

calls
the TimerState.RaiseStatus method, which raises an event. Form1 catches

the
event and adds a ListViewItem to a ListView:

private void AddNewStatus(string message)

{

Tracer.WriteLine("Form1.AddNewStatus", "Entering sub. Message: " +

message);

ListViewItem lvi = new ListViewItem(DateTime.Now.ToString("hh:mm:ss"));

Tracer.WriteLine("Form1.AddNewStatus", "After creating lvi");

lvi.SubItems.Add(message);

Tracer.WriteLine("Form1.AddNewStatus", "After adding subitem");

listView1.Items.Add(lvi);

Tracer.WriteLine("Form1.AddNewStatus", "After adding lvi to listView");

listView1.Refresh();

Tracer.WriteLine("Form1.AddNewStatus", "Exiting sub.");

}

8. Sporadically, the AddNewStatus method hangs on
listView1.Items.Add(lvi). I first noticed this happening when I happend

to
dock the iPAQ while it was adding an item. The ActiveSync messagebox came up and hung, as did my process. I am now able to reproduce it at will by adding a MessageBox call prior to raising an event. The messagebox call
returns but the messagebox itself remains displayed on the screen, and my process hangs at the line mentioned above.



Nov 16 '05 #4

P: n/a
You are probably suffering the side effect of touching GUI controls from
non-GUI threads.
In your case a listview from a threading.timer. The answer is to use
Control.Invoke.

There is an explanation with links here:
http://www.zen13120.zen.co.uk/Blog/2...d-full-fx.html

Cheers
Daniel

"Dan" <da*@dontspamme.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
I've created a pocketpc app which has a startup form containing a
listview.
The form creates an object which in turn creates a System.Threading.Timer.
It keeps track of the Timer state using a TimerState object similar to the
example in the System.Threading.Timer documentation. The method which
handles the timer events, among other things, periodically calls a method
in
this TimerState object which raises an event to the startup form, which in
turn adds a record to the listview. Sporadically this code in the startup
form hangs when it tries to add the record to the listview:

listView1.Items.Add(lvi).

I first noticed this happening when I happend to dock the iPAQ while it
was
adding an item. The ActiveSync messagebox came up and hung, as did my
process. I am now able to reproduce it at will by adding a MessageBox
call
prior to raising the event. The messagebox call returns but the
messagebox
itself remains displayed on the screen, and my process hangs at the line
mentioned above.

Anyone have any thoughts on what's going on? The details of the
implementation are described below....Dan

1. Form1 creates an UploadLooper object.

2. UploadLooper creates a TimerState object, similar to the example
in
the System.Threading.Timer documentation.

3. The UploadLooper module also contains a delegate declaration,
along
with a declaration for an UploadEvent object derived from EventArgs:

public delegate void StatusEvent(Object sender, UploadEvent e);

4. The TimerState object declares the event and contains a
RaiseStatus
method which enables us to fire StatusEvent:

public class TimerState

{

public event StatusEvent StatusMessage; // Declaration of the event

...

public void RaiseStatus(string message)

{

Tracer.WriteLine("TimerState.RaiseStatus", "Before raising event");

if (StatusMessage != null)

StatusMessage(this, new UploadEvent(message));

Tracer.WriteLine("TimerState.RaiseStatus", "After raising event");

}

5. The TimerState object also contains a Timer property itself, which
references the Timer we are going to create. We start the timer via the
UploadLooper.StartTimer method as follows:

public void StartTimer(uint millisecondInterval)

{

// Create the delegate that handles the timer events

System.Threading.TimerCallback timerDelegate = new
TimerCallback(CheckStatus);

// Create a timer that waits one second, then invokes every
'millisecondInterval' milliseconds

// and give TimerState a reference to the timer so we can dispose it when
necessary

m_TimerState.TimerInterval = millisecondInterval;

m_TimerState.Timer = new System.Threading.Timer(timerDelegate,
m_TimerState,
(uint) 5000, millisecondInterval);

}

6. The CheckStatus method gets called when the Timer fires, and casts
the object it receives to a TimerState object:

static void CheckStatus(Object state)

{

TimerState timerState = (TimerState) state;

timerState.Timer.Change(Timeout.Infinite, Timeout.Infinite); // Disable
the
timer

7. CheckStatus then goes on to do its processing. Periodically,
calls
the TimerState.RaiseStatus method, which raises an event. Form1 catches
the
event and adds a ListViewItem to a ListView:

private void AddNewStatus(string message)

{

Tracer.WriteLine("Form1.AddNewStatus", "Entering sub. Message: " +
message);

ListViewItem lvi = new ListViewItem(DateTime.Now.ToString("hh:mm:ss"));

Tracer.WriteLine("Form1.AddNewStatus", "After creating lvi");

lvi.SubItems.Add(message);

Tracer.WriteLine("Form1.AddNewStatus", "After adding subitem");

listView1.Items.Add(lvi);

Tracer.WriteLine("Form1.AddNewStatus", "After adding lvi to listView");

listView1.Refresh();

Tracer.WriteLine("Form1.AddNewStatus", "Exiting sub.");

}

8. Sporadically, the AddNewStatus method hangs on
listView1.Items.Add(lvi). I first noticed this happening when I happend
to
dock the iPAQ while it was adding an item. The ActiveSync messagebox came
up and hung, as did my process. I am now able to reproduce it at will by
adding a MessageBox call prior to raising an event. The messagebox call
returns but the messagebox itself remains displayed on the screen, and my
process hangs at the line mentioned above.


Nov 16 '05 #5

P: n/a
It works out of pure luck. The issue is there's a lock condition that may
or may not be in a safe state when you access the UI, so sometimes it will
work, other times it won't.

http://www.demsey.org/blog/PermaLink...8-837c35e7d26c

--
<ctacke/>
www.OpenNETCF.org
Your CF searches start and end here
"Dan" <da*@dontspamme.com> wrote in message
news:Om**************@TK2MSFTNGP15.phx.gbl...
If that is true, then why does this code *ever* work? (It almost always
does).

Also-- can you point me to a good article on Invoke? Thanks very much...Dan
"Chris Tacke, eMVP" <ct****@spamfree-opennetcf.org> wrote in message
news:uH**************@TK2MSFTNGP15.phx.gbl...
You cannot affect the UI from a worker thread, which the Thread.Timer is.
You *must* use Invoke to marshal calls to the UI.

<ctacke/>
www.opennetcf.org
"Dan" <da*@dontspamme.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
I've created a pocketpc app which has a startup form containing a listview.
The form creates an object which in turn creates a System.Threading.Timer. It keeps track of the Timer state using a TimerState object similar to the example in the System.Threading.Timer documentation. The method which
handles the timer events, among other things, periodically calls a method
in
this TimerState object which raises an event to the startup form, which in turn adds a record to the listview. Sporadically this code in the startup form hangs when it tries to add the record to the listview:

listView1.Items.Add(lvi).

I first noticed this happening when I happend to dock the iPAQ while
it was
adding an item. The ActiveSync messagebox came up and hung, as did my
process. I am now able to reproduce it at will by adding a MessageBox

call
prior to raising the event. The messagebox call returns but the

messagebox
itself remains displayed on the screen, and my process hangs at the
line mentioned above.

Anyone have any thoughts on what's going on? The details of the
implementation are described below....Dan

1. Form1 creates an UploadLooper object.

2. UploadLooper creates a TimerState object, similar to the example in
the System.Threading.Timer documentation.

3. The UploadLooper module also contains a delegate declaration,

along
with a declaration for an UploadEvent object derived from EventArgs:

public delegate void StatusEvent(Object sender, UploadEvent e);

4. The TimerState object declares the event and contains a

RaiseStatus
method which enables us to fire StatusEvent:

public class TimerState

{

public event StatusEvent StatusMessage; // Declaration of the
event
...

public void RaiseStatus(string message)

{

Tracer.WriteLine("TimerState.RaiseStatus", "Before raising event");

if (StatusMessage != null)

StatusMessage(this, new UploadEvent(message));

Tracer.WriteLine("TimerState.RaiseStatus", "After raising event");

}

5. The TimerState object also contains a Timer property itself,

which references the Timer we are going to create. We start the timer via the UploadLooper.StartTimer method as follows:

public void StartTimer(uint millisecondInterval)

{

// Create the delegate that handles the timer events

System.Threading.TimerCallback timerDelegate = new
TimerCallback(CheckStatus);

// Create a timer that waits one second, then invokes every
'millisecondInterval' milliseconds

// and give TimerState a reference to the timer so we can dispose it when necessary

m_TimerState.TimerInterval = millisecondInterval;

m_TimerState.Timer = new System.Threading.Timer(timerDelegate,

m_TimerState,
(uint) 5000, millisecondInterval);

}

6. The CheckStatus method gets called when the Timer fires, and casts the object it receives to a TimerState object:

static void CheckStatus(Object state)

{

TimerState timerState = (TimerState) state;

timerState.Timer.Change(Timeout.Infinite, Timeout.Infinite); // Disable the
timer

7. CheckStatus then goes on to do its processing. Periodically,

calls
the TimerState.RaiseStatus method, which raises an event. Form1
catches
the
event and adds a ListViewItem to a ListView:

private void AddNewStatus(string message)

{

Tracer.WriteLine("Form1.AddNewStatus", "Entering sub. Message: " +

message);

ListViewItem lvi = new
ListViewItem(DateTime.Now.ToString("hh:mm:ss"));
Tracer.WriteLine("Form1.AddNewStatus", "After creating lvi");

lvi.SubItems.Add(message);

Tracer.WriteLine("Form1.AddNewStatus", "After adding subitem");

listView1.Items.Add(lvi);

Tracer.WriteLine("Form1.AddNewStatus", "After adding lvi to listView");
listView1.Refresh();

Tracer.WriteLine("Form1.AddNewStatus", "Exiting sub.");

}

8. Sporadically, the AddNewStatus method hangs on
listView1.Items.Add(lvi). I first noticed this happening when I happend to
dock the iPAQ while it was adding an item. The ActiveSync messagebox

came up and hung, as did my process. I am now able to reproduce it at will by adding a MessageBox call prior to raising an event. The messagebox
call returns but the messagebox itself remains displayed on the screen, and

my process hangs at the line mentioned above.




Nov 16 '05 #6

P: n/a
Dan
Daniel, another respondent to this thread, pointed me to the following
article, which points out a way to work around the compact framework
limitation that you are unable pass arguments via Invoke:
http://www.zen13120.zen.co.uk/Blog/2...d-full-fx.html

I am thinking of implementing the workaround as follows:

1. Create a Queue object in the object from which I start the timer thread
2. When I want to pass an argument from the worker thread, SyncLock the
Queue, Enqueue the argument ( a string) to the queue, then End SyncLock the
queue.
3. Invoke an EventHandler in the GUI thread
4. The EventHandler gets a reference to the Queue object from the object
encapsulating the worker thread.
5. In the EventHandler, SyncLock the retrieved Queue object, Dequeue any
enqueued objects, and End Synclock the retrieved Queue.
6. Add the retrieved string to the listview

Does anyone see any problems with this?

Thanks...

Dan

"Chris Tacke, eMVP" <ct****@spamfree-opennetcf.org> wrote in message
news:eR**************@TK2MSFTNGP11.phx.gbl...
It works out of pure luck. The issue is there's a lock condition that may
or may not be in a safe state when you access the UI, so sometimes it will
work, other times it won't.

http://www.demsey.org/blog/PermaLink...8-837c35e7d26c
--
<ctacke/>
www.OpenNETCF.org
Your CF searches start and end here
"Dan" <da*@dontspamme.com> wrote in message
news:Om**************@TK2MSFTNGP15.phx.gbl...
If that is true, then why does this code *ever* work? (It almost always
does).

Also-- can you point me to a good article on Invoke? Thanks very

much...Dan

"Chris Tacke, eMVP" <ct****@spamfree-opennetcf.org> wrote in message
news:uH**************@TK2MSFTNGP15.phx.gbl...
You cannot affect the UI from a worker thread, which the Thread.Timer is. You *must* use Invoke to marshal calls to the UI.

<ctacke/>
www.opennetcf.org
"Dan" <da*@dontspamme.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
> I've created a pocketpc app which has a startup form containing a
listview.
> The form creates an object which in turn creates a

System.Threading.Timer.
> It keeps track of the Timer state using a TimerState object similar to
the
> example in the System.Threading.Timer documentation. The method
which > handles the timer events, among other things, periodically calls a

method
in
> this TimerState object which raises an event to the startup form, which
in
> turn adds a record to the listview. Sporadically this code in the

startup
> form hangs when it tries to add the record to the listview:
>
>
>
> listView1.Items.Add(lvi).
>
>
>
> I first noticed this happening when I happend to dock the iPAQ while

it was
> adding an item. The ActiveSync messagebox came up and hung, as did my > process. I am now able to reproduce it at will by adding a MessageBox call
> prior to raising the event. The messagebox call returns but the
messagebox
> itself remains displayed on the screen, and my process hangs at the line > mentioned above.
>
>
>
> Anyone have any thoughts on what's going on? The details of the
> implementation are described below....Dan
>
>
>
>
>
> 1. Form1 creates an UploadLooper object.
>
> 2. UploadLooper creates a TimerState object, similar to the example in
> the System.Threading.Timer documentation.
>
> 3. The UploadLooper module also contains a delegate declaration, along
> with a declaration for an UploadEvent object derived from EventArgs:
>
>
>
> public delegate void StatusEvent(Object sender, UploadEvent e);
>
>
>
> 4. The TimerState object declares the event and contains a
RaiseStatus
> method which enables us to fire StatusEvent:
>
>
>
> public class TimerState
>
> {
>
> public event StatusEvent StatusMessage; // Declaration of the event >
> ...
>
>
>
> public void RaiseStatus(string message)
>
> {
>
> Tracer.WriteLine("TimerState.RaiseStatus", "Before raising event");
>
> if (StatusMessage != null)
>
> StatusMessage(this, new UploadEvent(message));
>
> Tracer.WriteLine("TimerState.RaiseStatus", "After raising event");
>
> }
>
>
>
> 5. The TimerState object also contains a Timer property itself,

which
> references the Timer we are going to create. We start the timer via the > UploadLooper.StartTimer method as follows:
>
>
>
> public void StartTimer(uint millisecondInterval)
>
> {
>
> // Create the delegate that handles the timer events
>
> System.Threading.TimerCallback timerDelegate = new
> TimerCallback(CheckStatus);
>
> // Create a timer that waits one second, then invokes every
> 'millisecondInterval' milliseconds
>
> // and give TimerState a reference to the timer so we can dispose it

when
> necessary
>
> m_TimerState.TimerInterval = millisecondInterval;
>
> m_TimerState.Timer = new System.Threading.Timer(timerDelegate,
m_TimerState,
> (uint) 5000, millisecondInterval);
>
> }
>
>
>
> 6. The CheckStatus method gets called when the Timer fires, and

casts
> the object it receives to a TimerState object:
>
>
>
> static void CheckStatus(Object state)
>
> {
>
> TimerState timerState = (TimerState) state;
>
> timerState.Timer.Change(Timeout.Infinite, Timeout.Infinite); // Disable the
> timer
>
>
>
>
>
> 7. CheckStatus then goes on to do its processing. Periodically, calls
> the TimerState.RaiseStatus method, which raises an event. Form1 catches the
> event and adds a ListViewItem to a ListView:
>
>
>
> private void AddNewStatus(string message)
>
> {
>
> Tracer.WriteLine("Form1.AddNewStatus", "Entering sub. Message: " +
message);
>
> ListViewItem lvi = new ListViewItem(DateTime.Now.ToString("hh:mm:ss")); >
> Tracer.WriteLine("Form1.AddNewStatus", "After creating lvi");
>
> lvi.SubItems.Add(message);
>
> Tracer.WriteLine("Form1.AddNewStatus", "After adding subitem");
>
> listView1.Items.Add(lvi);
>
> Tracer.WriteLine("Form1.AddNewStatus", "After adding lvi to listView"); >
> listView1.Refresh();
>
> Tracer.WriteLine("Form1.AddNewStatus", "Exiting sub.");
>
> }
>
>
>
> 8. Sporadically, the AddNewStatus method hangs on
> listView1.Items.Add(lvi). I first noticed this happening when I happend to
> dock the iPAQ while it was adding an item. The ActiveSync
messagebox came
> up and hung, as did my process. I am now able to reproduce it at
will by
> adding a MessageBox call prior to raising an event. The messagebox call > returns but the messagebox itself remains displayed on the screen,

and my
> process hangs at the line mentioned above.
>
>
>
>
>
>



Nov 16 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.