Background thread with lower priority

  • Thread starter Jeffry van de Vuurst
  • Start date
J

Jeffry van de Vuurst

Hi,

I have a CF 2.0 app that uses 2 background threads. 1 for polling for a
network connection and 1 for performing a background sync.

First I used the OpenNETCF BackgroundWorker for this purpose. However, when
performing a background sync the UI became unresponsive. Now I changed it to
a regular thead using:
Thread backgroundSyncThread = new Thread(DoBackgroundSync);
backgroundSyncThread.Priority = ThreadPriority.Lowest;
backgroundSyncThread.IsBackground = true;
backgroundSyncThread.Start();

However, I read here
http://www.danielmoth.com/Blog/2004/08/threads-and-threadpriority-with-net.html,
that chaging the priority of threads may be risky because garbage collection
could run on the low priority thread.

It's an article from August 2004 but does mention CF 2.0 beta 1. Does this
still apply? And if so, what are other ways to make sure that the
(potentially long) running background thread doesn't freeze the UI? Is doing
a Thread.Sleep(0) from the worker thread effective? I've read different
stories about the effectiveness of Thread.Sleep(0)...

Thanks,
 
G

Guest

If a GC occurs, all threads in the process are suspended. Doesn't matter
what priority any of the threads are.

Are you sure it is a GC that's causing the non-responsiveness?
 
J

Jeffry van de Vuurst

Hi Chris,

Thanks for your reply. I guess my question was not clear enough.

It's not the GC that causes the non-responsiveness. My assumption is that
the non-responsiveness is caused by running my background sync on a thread
with the same priority as the main thread. So when the background sync
starts, both the UI and the sync are competing for the CPU cycles, right?

That's the reason I started creating my own thread and setting the priority
lower than the main thread. However, the blog post from Daniel Moth gives me
some concerns because it discourages changing the priority of a thread
because of unexpected behavior (mentioning the garbage collection). At
least, that is my understanding of the article.

So maybe my question should be: is it ok to have a background thread running
on a lower priority so not to interfere with the GUI, or does running on
lower priority have unexpected side effects (like mentioned in the article)
and should be avoided?

Thanks,

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
If a GC occurs, all threads in the process are suspended. Doesn't matter
what priority any of the threads are.

Are you sure it is a GC that's causing the non-responsiveness?
 
G

Ginny Caughey [MVP]

Jeffrey,

I have desktop apps that run worker threads on lower priorities without
problems. I don't happen to have CF apps that do, but I'd suggest just
trying it. Do you have a link to Daniel's post? He doesn't usually get
things wrong so I should read it.

--
Ginny Caughey
Device Application Development MVP


Jeffry van de Vuurst said:
Hi Chris,

Thanks for your reply. I guess my question was not clear enough.

It's not the GC that causes the non-responsiveness. My assumption is that
the non-responsiveness is caused by running my background sync on a thread
with the same priority as the main thread. So when the background sync
starts, both the UI and the sync are competing for the CPU cycles, right?

That's the reason I started creating my own thread and setting the
priority lower than the main thread. However, the blog post from Daniel
Moth gives me some concerns because it discourages changing the priority
of a thread because of unexpected behavior (mentioning the garbage
collection). At least, that is my understanding of the article.

So maybe my question should be: is it ok to have a background thread
running on a lower priority so not to interfere with the GUI, or does
running on lower priority have unexpected side effects (like mentioned in
the article) and should be avoided?

Thanks,
 
G

Guest

If it's on a background thread it's going to compete for resources just like
anything running, but it should never cause the UI to lock unless it's using
100% of the CPU, and in that case it's poorly designed and would cause the
problem no matter where you put it.

Running it at a lower priority would allow the UI to get quantum before the
background worker, but it wouldn't fit the flaw in what the thread is doing,
or help your battery life.

You've got something wrong in how you're either creating and using the
thread, or in what it's doing. We'd need to see code to tell you more.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--



Jeffry van de Vuurst said:
Hi Chris,

Thanks for your reply. I guess my question was not clear enough.

It's not the GC that causes the non-responsiveness. My assumption is that
the non-responsiveness is caused by running my background sync on a thread
with the same priority as the main thread. So when the background sync
starts, both the UI and the sync are competing for the CPU cycles, right?

That's the reason I started creating my own thread and setting the
priority lower than the main thread. However, the blog post from Daniel
Moth gives me some concerns because it discourages changing the priority
of a thread because of unexpected behavior (mentioning the garbage
collection). At least, that is my understanding of the article.

So maybe my question should be: is it ok to have a background thread
running on a lower priority so not to interfere with the GUI, or does
running on lower priority have unexpected side effects (like mentioned in
the article) and should be avoided?

Thanks,
 
J

Jeffry van de Vuurst

Well, the background sync doesn't completely lock the UI, it just makes it a
lot slower. It does quite a lot. It does some local database calls, does
some webservice calls and if there's new data, it loops through all the
records and saves them to the local database. This is quite an intensive
process. However, when checking for updates and there's nothing new, the
background sync takes about 20 seconds.

Posting the complete code of what the sync does goes too far. Here's my code
to start the thread:
private static void StartBackgroundThread()
{
Thread backgroundSyncThread = new Thread(DoBackgroundSync);
backgroundSyncThread.Priority = ThreadPriority.Lowest;
backgroundSyncThread.IsBackground = true;
backgroundSyncThread.Start();
}

And here's the DoBackgroundSync method:
private static void DoBackgroundSync()
{
_backgroundThreadRunning = true;

// Wait a while so that the automatic backgroundsync won't interfere
with the startup of the application
Thread.Sleep(60000);

// While the EnableBackgroundSync property is set to true continue to
sync
while (_enableBackgroundSync)
{
if (!BackgroundSyncRunning & !_syncRunning)
{
if (!_connectionManager.IsConnected)
{
try
{
_connectionManager.CheckConnection();
}
catch (Exception ex)
{
TextLogger.Log(TextLogger.LogLevelType.Error, "SyncManager
BackgroundSync Connection error: {0}", ex.ToString());
}
}

if (_connectionManager.IsConnected &&
!AppSettings.InitializeApplication) // don't perform a backgroundsync while
initializing the app
{
_backgroundSyncRunning = true;

// First, stop automatic dispatching
if (!AppSettings.WorkOffline && _requestManager.Running)
StopAutomaticDispatch();

try
{
StartSync(null);
}
catch(Exception ex)
{
TextLogger.Log(TextLogger.LogLevelType.Error, "Error during Background
Sync: {0}", ex.ToString());
}

while (BackgroundSyncRunning)
{
// Wait for backgroundsync to finish
}

// When finished with Sync, restart automatic dispatching
if (!AppSettings.WorkOffline && !_requestManager.Running)
StartAutomaticDispatch();
}
}

if (_enableBackgroundSync)
{
TextLogger.Log(TextLogger.LogLevelType.Info, "SyncManager
BackgroundSync: sleeping for {0} minutes", AppSettings.SyncInterval);

// Put the thread to sleep for the interval
Thread.Sleep(AppSettings.SyncInterval*60*1000);
}
}

_backgroundThreadRunning = false;
}

The call to StartSync(null) does all the hard work :).
 
P

Paul G. Tobey [eMVP]

So, you want to prioritize that below the rest of the UI. That's fine, but
you should understand that the priority means that, as long as the UI is
doing *anything*, your background thread will get *zero* time (not just a
small amount of time, not almost no time, absolutely no time). You
certainly don't want to set its priority to lowest, or I wouldn't want to
set its priority to lowest, at least. If the UI is waiting, at any time,
for something from the background thread to be complete, it will almost
certainly wait forever. You might try setting it just below the priority of
the UI thread, or you might alter the code, leaving the priority at the
default, so that it periodically goes to sleep for a little while.

Paul T.
 
G

Guest

I agree - I'd see if a few yields (Sleep(0)) in the worker thread alleviate
things.

Lowering the priority runs the risk of the worker taking an eternity to
complete.
 
J

Jeffry van de Vuurst

Ok, thank you all for you suggestions and explanations!

About the UI waiting for the background thread. That's no issue to my
knowledge. The UI doesn't wait on the background thread to complete, they're
independent.

I see your point that the background thread doesn't get any time as long as
the UI is doing anything. But as I understand it, even if I would set the
Priority to BelowNormal, it wouldn't get any time because the UI still has a
higher priority, right?

I'll try your suggestion of doing some yielding in the background thread.

Another quick question. If I go for the Sleep(0) option would you suggest to
use the OpenNETCF BackgroundWorker again or should I just stay with creating
my own threads? In other words, does the backgroundworker have any
(performance/memory) advantage over creating my own threads?

Thanks again,

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
I agree - I'd see if a few yields (Sleep(0)) in the worker thread alleviate
things.

Lowering the priority runs the risk of the worker taking an eternity to
complete.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--


"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam DOT
com> wrote in message news:[email protected]...
So, you want to prioritize that below the rest of the UI. That's fine,
but you should understand that the priority means that, as long as the UI
is doing *anything*, your background thread will get *zero* time (not
just a small amount of time, not almost no time, absolutely no time).
You certainly don't want to set its priority to lowest, or I wouldn't
want to set its priority to lowest, at least. If the UI is waiting, at
any time, for something from the background thread to be complete, it
will almost certainly wait forever. You might try setting it just below
the priority of the UI thread, or you might alter the code, leaving the
priority at the default, so that it periodically goes to sleep for a
little while.

Paul T.
 
G

Guest

Correct, priority is irrelevent. The GC runs on the thread that attempted
the allocation that triggered GC, but the first thing the GC does is suspend
all other managed threads in the currently running process, so if GC
hap[pens in a worker, the UI still suspends.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--


Ginny Caughey said:
Thanks for the link. As I read it, since GC occurs on whatever thread is
running when GC needs collecting, the thread priority probably wouldn't
matter since that thread is running whatever its priority. At least that's
the way I hope it works.
 
P

Paul G. Tobey [eMVP]

Remember that threads are scheduled against *all* other threads in the
system, not just against other threads in the same application. If there's
*any* thread in the system with a higher priority than you and it is in the
ready to run state, you get zero time.

Paul T.

Jeffry van de Vuurst said:
Ok, thank you all for you suggestions and explanations!

About the UI waiting for the background thread. That's no issue to my
knowledge. The UI doesn't wait on the background thread to complete,
they're independent.

I see your point that the background thread doesn't get any time as long
as the UI is doing anything. But as I understand it, even if I would set
the Priority to BelowNormal, it wouldn't get any time because the UI still
has a higher priority, right?

I'll try your suggestion of doing some yielding in the background thread.

Another quick question. If I go for the Sleep(0) option would you suggest
to use the OpenNETCF BackgroundWorker again or should I just stay with
creating my own threads? In other words, does the backgroundworker have
any (performance/memory) advantage over creating my own threads?

Thanks again,

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
I agree - I'd see if a few yields (Sleep(0)) in the worker thread
alleviate things.

Lowering the priority runs the risk of the worker taking an eternity to
complete.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--


"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam
DOT com> wrote in message news:[email protected]...
So, you want to prioritize that below the rest of the UI. That's fine,
but you should understand that the priority means that, as long as the
UI is doing *anything*, your background thread will get *zero* time (not
just a small amount of time, not almost no time, absolutely no time).
You certainly don't want to set its priority to lowest, or I wouldn't
want to set its priority to lowest, at least. If the UI is waiting, at
any time, for something from the background thread to be complete, it
will almost certainly wait forever. You might try setting it just below
the priority of the UI thread, or you might alter the code, leaving the
priority at the default, so that it periodically goes to sleep for a
little while.

Paul T.

message Well, the background sync doesn't completely lock the UI, it just makes
it a lot slower. It does quite a lot. It does some local database
calls, does some webservice calls and if there's new data, it loops
through all the records and saves them to the local database. This is
quite an intensive process. However, when checking for updates and
there's nothing new, the background sync takes about 20 seconds.

Posting the complete code of what the sync does goes too far. Here's my
code to start the thread:
private static void StartBackgroundThread()
{
Thread backgroundSyncThread = new Thread(DoBackgroundSync);
backgroundSyncThread.Priority = ThreadPriority.Lowest;
backgroundSyncThread.IsBackground = true;
backgroundSyncThread.Start();
}

And here's the DoBackgroundSync method:
private static void DoBackgroundSync()
{
_backgroundThreadRunning = true;

// Wait a while so that the automatic backgroundsync won't interfere
with the startup of the application
Thread.Sleep(60000);

// While the EnableBackgroundSync property is set to true continue
to sync
while (_enableBackgroundSync)
{
if (!BackgroundSyncRunning & !_syncRunning)
{
if (!_connectionManager.IsConnected)
{
try
{
_connectionManager.CheckConnection();
}
catch (Exception ex)
{
TextLogger.Log(TextLogger.LogLevelType.Error, "SyncManager
BackgroundSync Connection error: {0}", ex.ToString());
}
}

if (_connectionManager.IsConnected &&
!AppSettings.InitializeApplication) // don't perform a backgroundsync
while initializing the app
{
_backgroundSyncRunning = true;

// First, stop automatic dispatching
if (!AppSettings.WorkOffline && _requestManager.Running)
StopAutomaticDispatch();

try
{
StartSync(null);
}
catch(Exception ex)
{
TextLogger.Log(TextLogger.LogLevelType.Error, "Error during
Background Sync: {0}", ex.ToString());
}

while (BackgroundSyncRunning)
{
// Wait for backgroundsync to finish
}

// When finished with Sync, restart automatic dispatching
if (!AppSettings.WorkOffline && !_requestManager.Running)
StartAutomaticDispatch();
}
}

if (_enableBackgroundSync)
{
TextLogger.Log(TextLogger.LogLevelType.Info, "SyncManager
BackgroundSync: sleeping for {0} minutes", AppSettings.SyncInterval);

// Put the thread to sleep for the interval
Thread.Sleep(AppSettings.SyncInterval*60*1000);
}
}

_backgroundThreadRunning = false;
}

The call to StartSync(null) does all the hard work :).



--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
If it's on a background thread it's going to compete for resources
just like anything running, but it should never cause the UI to lock
unless it's using 100% of the CPU, and in that case it's poorly
designed and would cause the problem no matter where you put it.

Running it at a lower priority would allow the UI to get quantum
before the background worker, but it wouldn't fit the flaw in what the
thread is doing, or help your battery life.

You've got something wrong in how you're either creating and using the
thread, or in what it's doing. We'd need to see code to tell you more.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--



message Hi Chris,

Thanks for your reply. I guess my question was not clear enough.

It's not the GC that causes the non-responsiveness. My assumption is
that the non-responsiveness is caused by running my background sync
on a thread with the same priority as the main thread. So when the
background sync starts, both the UI and the sync are competing for
the CPU cycles, right?

That's the reason I started creating my own thread and setting the
priority lower than the main thread. However, the blog post from
Daniel Moth gives me some concerns because it discourages changing
the priority of a thread because of unexpected behavior (mentioning
the garbage collection). At least, that is my understanding of the
article.

So maybe my question should be: is it ok to have a background thread
running on a lower priority so not to interfere with the GUI, or does
running on lower priority have unexpected side effects (like
mentioned in the article) and should be avoided?

Thanks,

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
If a GC occurs, all threads in the process are suspended. Doesn't
matter what priority any of the threads are.

Are you sure it is a GC that's causing the non-responsiveness?


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--


in message Hi,

I have a CF 2.0 app that uses 2 background threads. 1 for polling
for a network connection and 1 for performing a background sync.

First I used the OpenNETCF BackgroundWorker for this purpose.
However, when performing a background sync the UI became
unresponsive. Now I changed it to a regular thead using:
Thread backgroundSyncThread = new Thread(DoBackgroundSync);
backgroundSyncThread.Priority = ThreadPriority.Lowest;
backgroundSyncThread.IsBackground = true;
backgroundSyncThread.Start();

However, I read here
http://www.danielmoth.com/Blog/2004/08/threads-and-threadpriority-with-net.html,
that chaging the priority of threads may be risky because garbage
collection could run on the low priority thread.

It's an article from August 2004 but does mention CF 2.0 beta 1.
Does this still apply? And if so, what are other ways to make sure
that the (potentially long) running background thread doesn't
freeze the UI? Is doing a Thread.Sleep(0) from the worker thread
effective? I've read different stories about the effectiveness of
Thread.Sleep(0)...

Thanks,
 
G

Guest

About the UI waiting for the background thread. That's no issue to my
knowledge. The UI doesn't wait on the background thread to complete,
they're independent.

Not true. The processor can only do one thing at any given time, even if
you have many threads. The scheduler decides who gets to use the processor
at even given time based on priority. The amount of time that a thread gets
to use it is called quantum.

So if your UI and your worker are equal in priority, then the scheduler will
round-robin them into the processor (sure, it's more complex than that as
other stuff is happening and each thread isn't necessarily needing to do
something every time the scheduler checks - which, BTW, is every
millisecond).

If your UI is at a higher priority, the scheduler will always give it
precedence over the worker. So if your UI is doing something a lot (like
lots of painting very fast very often or something) then it's conceivable
that the scheduler will never let the worker run (or not until the higher
priority thread doesn't have anything to do).
I see your point that the background thread doesn't get any time as long
as the UI is doing anything. But as I understand it, even if I would set
the Priority to BelowNormal, it wouldn't get any time because the UI still
has a higher priority, right?

Correct. The issue with setting the worker to a lower priority isn't that
it might interrup thte UI, it's that the UI may never let the worker run.
Another possibility is if the main thread gets to a point where it's waiting
on the worker, but the worker is a lower priority and the scheduler never
gives it quantum. That's called a deadlock.
I'll try your suggestion of doing some yielding in the background thread.

Another quick question. If I go for the Sleep(0) option would you suggest
to use the OpenNETCF BackgroundWorker again or should I just stay with
creating my own threads? In other words, does the backgroundworker have
any (performance/memory) advantage over creating my own threads?

Makes no difference. The OpenNETCF BackgroundWorker is just a logical
wrapper around a thread. The same as what you'd end up if you wrote your
own thread handling.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--
 
J

Jeffry van de Vuurst

Ah ok, I see. Thanks again!

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam DOT
com> wrote in message news:[email protected]...
Remember that threads are scheduled against *all* other threads in the
system, not just against other threads in the same application. If
there's *any* thread in the system with a higher priority than you and it
is in the ready to run state, you get zero time.

Paul T.

Jeffry van de Vuurst said:
Ok, thank you all for you suggestions and explanations!

About the UI waiting for the background thread. That's no issue to my
knowledge. The UI doesn't wait on the background thread to complete,
they're independent.

I see your point that the background thread doesn't get any time as long
as the UI is doing anything. But as I understand it, even if I would set
the Priority to BelowNormal, it wouldn't get any time because the UI
still has a higher priority, right?

I'll try your suggestion of doing some yielding in the background thread.

Another quick question. If I go for the Sleep(0) option would you suggest
to use the OpenNETCF BackgroundWorker again or should I just stay with
creating my own threads? In other words, does the backgroundworker have
any (performance/memory) advantage over creating my own threads?

Thanks again,

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
I agree - I'd see if a few yields (Sleep(0)) in the worker thread
alleviate things.

Lowering the priority runs the risk of the worker taking an eternity to
complete.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--


"Paul G. Tobey [eMVP]" <p space tobey no spam AT no instrument no spam
DOT com> wrote in message So, you want to prioritize that below the rest of the UI. That's fine,
but you should understand that the priority means that, as long as the
UI is doing *anything*, your background thread will get *zero* time
(not just a small amount of time, not almost no time, absolutely no
time). You certainly don't want to set its priority to lowest, or I
wouldn't want to set its priority to lowest, at least. If the UI is
waiting, at any time, for something from the background thread to be
complete, it will almost certainly wait forever. You might try setting
it just below the priority of the UI thread, or you might alter the
code, leaving the priority at the default, so that it periodically goes
to sleep for a little while.

Paul T.

message Well, the background sync doesn't completely lock the UI, it just
makes it a lot slower. It does quite a lot. It does some local
database calls, does some webservice calls and if there's new data, it
loops through all the records and saves them to the local database.
This is quite an intensive process. However, when checking for updates
and there's nothing new, the background sync takes about 20 seconds.

Posting the complete code of what the sync does goes too far. Here's
my code to start the thread:
private static void StartBackgroundThread()
{
Thread backgroundSyncThread = new Thread(DoBackgroundSync);
backgroundSyncThread.Priority = ThreadPriority.Lowest;
backgroundSyncThread.IsBackground = true;
backgroundSyncThread.Start();
}

And here's the DoBackgroundSync method:
private static void DoBackgroundSync()
{
_backgroundThreadRunning = true;

// Wait a while so that the automatic backgroundsync won't
interfere with the startup of the application
Thread.Sleep(60000);

// While the EnableBackgroundSync property is set to true continue
to sync
while (_enableBackgroundSync)
{
if (!BackgroundSyncRunning & !_syncRunning)
{
if (!_connectionManager.IsConnected)
{
try
{
_connectionManager.CheckConnection();
}
catch (Exception ex)
{
TextLogger.Log(TextLogger.LogLevelType.Error, "SyncManager
BackgroundSync Connection error: {0}", ex.ToString());
}
}

if (_connectionManager.IsConnected &&
!AppSettings.InitializeApplication) // don't perform a backgroundsync
while initializing the app
{
_backgroundSyncRunning = true;

// First, stop automatic dispatching
if (!AppSettings.WorkOffline && _requestManager.Running)
StopAutomaticDispatch();

try
{
StartSync(null);
}
catch(Exception ex)
{
TextLogger.Log(TextLogger.LogLevelType.Error, "Error during
Background Sync: {0}", ex.ToString());
}

while (BackgroundSyncRunning)
{
// Wait for backgroundsync to finish
}

// When finished with Sync, restart automatic dispatching
if (!AppSettings.WorkOffline && !_requestManager.Running)
StartAutomaticDispatch();
}
}

if (_enableBackgroundSync)
{
TextLogger.Log(TextLogger.LogLevelType.Info, "SyncManager
BackgroundSync: sleeping for {0} minutes", AppSettings.SyncInterval);

// Put the thread to sleep for the interval
Thread.Sleep(AppSettings.SyncInterval*60*1000);
}
}

_backgroundThreadRunning = false;
}

The call to StartSync(null) does all the hard work :).



--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
If it's on a background thread it's going to compete for resources
just like anything running, but it should never cause the UI to lock
unless it's using 100% of the CPU, and in that case it's poorly
designed and would cause the problem no matter where you put it.

Running it at a lower priority would allow the UI to get quantum
before the background worker, but it wouldn't fit the flaw in what
the thread is doing, or help your battery life.

You've got something wrong in how you're either creating and using
the thread, or in what it's doing. We'd need to see code to tell you
more.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--



in message Hi Chris,

Thanks for your reply. I guess my question was not clear enough.

It's not the GC that causes the non-responsiveness. My assumption is
that the non-responsiveness is caused by running my background sync
on a thread with the same priority as the main thread. So when the
background sync starts, both the UI and the sync are competing for
the CPU cycles, right?

That's the reason I started creating my own thread and setting the
priority lower than the main thread. However, the blog post from
Daniel Moth gives me some concerns because it discourages changing
the priority of a thread because of unexpected behavior (mentioning
the garbage collection). At least, that is my understanding of the
article.

So maybe my question should be: is it ok to have a background thread
running on a lower priority so not to interfere with the GUI, or
does running on lower priority have unexpected side effects (like
mentioned in the article) and should be avoided?

Thanks,

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
If a GC occurs, all threads in the process are suspended. Doesn't
matter what priority any of the threads are.

Are you sure it is a GC that's causing the non-responsiveness?


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--


in message Hi,

I have a CF 2.0 app that uses 2 background threads. 1 for polling
for a network connection and 1 for performing a background sync.

First I used the OpenNETCF BackgroundWorker for this purpose.
However, when performing a background sync the UI became
unresponsive. Now I changed it to a regular thead using:
Thread backgroundSyncThread = new Thread(DoBackgroundSync);
backgroundSyncThread.Priority = ThreadPriority.Lowest;
backgroundSyncThread.IsBackground = true;
backgroundSyncThread.Start();

However, I read here
http://www.danielmoth.com/Blog/2004/08/threads-and-threadpriority-with-net.html,
that chaging the priority of threads may be risky because garbage
collection could run on the low priority thread.

It's an article from August 2004 but does mention CF 2.0 beta 1.
Does this still apply? And if so, what are other ways to make sure
that the (potentially long) running background thread doesn't
freeze the UI? Is doing a Thread.Sleep(0) from the worker thread
effective? I've read different stories about the effectiveness of
Thread.Sleep(0)...

Thanks,
 
D

Daniel Moth

Hi Jeffry

The blog entry I wrote in 2004 is something I still stand by today. Only one
thing has changed which is the number of threads in the threadpool (not 256
anymore), but that doesn't detract from my point that much.

It has two questions and a statement:
Q1. "So if you change the priority of other threads in your app how will
they play nicely with the above four?"
Q2. "What will the results be if that happened to be one of your own threads
whose priority you lowered?"
S1. "if you are going to be creating threads and changing their priority you
must first be sure you understand the above and cater for them in your
design"

The first point is about knowing that you have 3 additional threads not
under your control. Design for that.

The 2nd point is about the GC running on whatever thread happens to be
running (*unlike* the desktop). Unlike the previous point, this has nothing
to do with other threads in your app (as others pointed out) but has to be
considered at the system as a whole (other threads are also running on the
system, as others pointed out).

Once you understand the implications of the above, my statement kicks in: If
you know what you are doing, go for it.

Nothing above is controversial. I can potentially be controversial by saying
that 99.99% of managed apps out there do not need to lower the priority of
any of their threads; in my *personal* opinion.

If you have any further questions regarding my blog entries please feel free
to email me. For questions specific to your needs/work, please continue to
use this group.

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Correct, priority is irrelevent. The GC runs on the thread that attempted
the allocation that triggered GC, but the first thing the GC does is
suspend all other managed threads in the currently running process, so if
GC hap[pens in a worker, the UI still suspends.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
 
J

Jeffry van de Vuurst

Hi Daniel,

Thanks for the clarification. If I follow your personal opinion, I'll assume
that my app falls in the 99% category, so I will try to get it working
without lowering the priority :)

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
Daniel Moth said:
Hi Jeffry

The blog entry I wrote in 2004 is something I still stand by today. Only
one thing has changed which is the number of threads in the threadpool
(not 256 anymore), but that doesn't detract from my point that much.

It has two questions and a statement:
Q1. "So if you change the priority of other threads in your app how will
they play nicely with the above four?"
Q2. "What will the results be if that happened to be one of your own
threads whose priority you lowered?"
S1. "if you are going to be creating threads and changing their priority
you must first be sure you understand the above and cater for them in your
design"

The first point is about knowing that you have 3 additional threads not
under your control. Design for that.

The 2nd point is about the GC running on whatever thread happens to be
running (*unlike* the desktop). Unlike the previous point, this has
nothing to do with other threads in your app (as others pointed out) but
has to be considered at the system as a whole (other threads are also
running on the system, as others pointed out).

Once you understand the implications of the above, my statement kicks in:
If you know what you are doing, go for it.

Nothing above is controversial. I can potentially be controversial by
saying that 99.99% of managed apps out there do not need to lower the
priority of any of their threads; in my *personal* opinion.

If you have any further questions regarding my blog entries please feel
free to email me. For questions specific to your needs/work, please
continue to use this group.

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Correct, priority is irrelevent. The GC runs on the thread that
attempted the allocation that triggered GC, but the first thing the GC
does is suspend all other managed threads in the currently running
process, so if GC hap[pens in a worker, the UI still suspends.


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--


Ginny Caughey said:
Thanks for the link. As I read it, since GC occurs on whatever thread is
running when GC needs collecting, the thread priority probably wouldn't
matter since that thread is running whatever its priority. At least
that's the way I hope it works.

--
Ginny Caughey
Device Application Development MVP


message Hi Ginny,

Here's the link:
http://www.danielmoth.com/Blog/2004/08/threads-and-threadpriority-with-net.html.

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
message Jeffrey,

I have desktop apps that run worker threads on lower priorities
without problems. I don't happen to have CF apps that do, but I'd
suggest just trying it. Do you have a link to Daniel's post? He
doesn't usually get things wrong so I should read it.

--
Ginny Caughey
Device Application Development MVP


message Hi Chris,

Thanks for your reply. I guess my question was not clear enough.

It's not the GC that causes the non-responsiveness. My assumption is
that the non-responsiveness is caused by running my background sync
on a thread with the same priority as the main thread. So when the
background sync starts, both the UI and the sync are competing for
the CPU cycles, right?

That's the reason I started creating my own thread and setting the
priority lower than the main thread. However, the blog post from
Daniel Moth gives me some concerns because it discourages changing
the priority of a thread because of unexpected behavior (mentioning
the garbage collection). At least, that is my understanding of the
article.

So maybe my question should be: is it ok to have a background thread
running on a lower priority so not to interfere with the GUI, or does
running on lower priority have unexpected side effects (like
mentioned in the article) and should be avoided?

Thanks,

--
Jeffry van de Vuurst
CWR Mobility
www.cwrmobility.com
--
If a GC occurs, all threads in the process are suspended. Doesn't
matter what priority any of the threads are.

Are you sure it is a GC that's causing the non-responsiveness?


--
Chris Tacke
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--


in message Hi,

I have a CF 2.0 app that uses 2 background threads. 1 for polling
for a network connection and 1 for performing a background sync.

First I used the OpenNETCF BackgroundWorker for this purpose.
However, when performing a background sync the UI became
unresponsive. Now I changed it to a regular thead using:
Thread backgroundSyncThread = new Thread(DoBackgroundSync);
backgroundSyncThread.Priority = ThreadPriority.Lowest;
backgroundSyncThread.IsBackground = true;
backgroundSyncThread.Start();

However, I read here
http://www.danielmoth.com/Blog/2004/08/threads-and-threadpriority-with-net.html,
that chaging the priority of threads may be risky because garbage
collection could run on the low priority thread.

It's an article from August 2004 but does mention CF 2.0 beta 1.
Does this still apply? And if so, what are other ways to make sure
that the (potentially long) running background thread doesn't
freeze the UI? Is doing a Thread.Sleep(0) from the worker thread
effective? I've read different stories about the effectiveness of
Thread.Sleep(0)...

Thanks,
 
P

Peter Huish

So if your UI and your worker are equal in priority, then the scheduler will
round-robin them into the processor (sure, it's more complex than that as
other stuff is happening and each thread isn't necessarily needing to do
something every time the scheduler checks - which, BTW, is every
millisecond).

Just a question out of interest here ...

Are thread priorities static throughout the life of the thread or can
their priority be boosted by the o/s in response to something like an
i/o completion?


thanks

pete
 
G

Guest

They are static unless something specifically calls CeSetThreadPriority to
change them. The OS never does this - it would only happen if an app did it
manually.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top