473,249 Members | 1,900 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,249 software developers and data experts.

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

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
6 2821
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Serge | last post by:
Hi, I am having a thread hang problem in my c# code. The example on the website: http://csharp.web1000.com/ is a simplified version of my problem. You will see in the form that a...
15
by: Jacob Crossley | last post by:
Hello all. We have about 10 Window's services that we wrote in c#. We use them to process row's that we have queued up in various SQL tables. The services seem to hang at least once in any given...
7
by: Pi | last post by:
I have an MDI parent with one or more children forms. Each child form has an engine thread that processes data. The child form's _Closing event is roughly 01 Private Sub...
12
by: Jack Russell | last post by:
My unstanding of all VB up to and including vb6 is that an event could not "interrupt" itself. For instance if you had a timer event containing a msgbox then you would only get one message. ...
3
by: Chris Dunaway | last post by:
Consider the following simple classes/interfaces defined below. When the derived class raises the events, on which thread is the event code run? Do I need to do anything to catch the events in my...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.