473,386 Members | 1,775 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,386 software developers and data experts.

Request review of this simple threading code

In the past I've had problems with using threads and getting all kinds of
weird bugs.
I've been reading over Jon Skeet's GREAT website about threading and have
tried to apply some of what I learned. There is almost too much information
there for me, I had a hard time deciding what method or design to choose.

I hoped that I could post this skeleton class for a quick review to make
sure I'm on the right track. If you have a minute, I would appreciate your
comments.

Expand|Select|Wrap|Line Numbers
  1. public class CalibrateDAQViewPresenter :
  2. FunctionalTestModulePresenter<ICalibrateDAQView>
  3. {
  4. private bool _stopping = false;
  5. private bool _stopped = false;
  6. private static readonly object _lockObject = new object();
  7.  
  8. protected override void Dispose(bool disposing)
  9. {
  10. // let the polling thread exit
  11. lock (_lockObject)
  12. {
  13. _stopping = false;
  14. while (_stopped == false) ;
  15. }
  16. base.Dispose(disposing);
  17. }
  18.  
  19. public void OnViewReady()
  20. {
  21. _startReadingData();
  22. }
  23.  
  24. private void _startReadingData()
  25. {
  26. _stopped = false;
  27. _stopping = false;
  28. ThreadPool.QueueUserWorkItem(
  29. delegate
  30. {
  31. _dataPoller();
  32. }
  33. );
  34. }
  35.  
  36. private void _dataPoller()
  37. {
  38. while(true)
  39. {
  40. lock(_lockObject)
  41. {
  42. if(_stopping)
  43. {
  44. _stopped = true;
  45. return;
  46. }
  47. // do stuff and update view
  48. }
  49.  
  50. Thread.Sleep(100);
  51. }
  52. }
  53. }
  54.  

Thanks for reading!
Aug 23 '06 #1
6 1269
Your code will deadlock upon Dispose. Dispose locks on _lockObject, but
does not release that lock until the thread has stopped. The thread on the
otherhand, requires that same lock in order to stop.

--
Adam Clauss

"sklett" <s@s.comwrote in message
news:e4**************@TK2MSFTNGP05.phx.gbl...
In the past I've had problems with using threads and getting all kinds of
weird bugs.
I've been reading over Jon Skeet's GREAT website about threading and have
tried to apply some of what I learned. There is almost too much
information there for me, I had a hard time deciding what method or design
to choose.

I hoped that I could post this skeleton class for a quick review to make
sure I'm on the right track. If you have a minute, I would appreciate
your comments.

Expand|Select|Wrap|Line Numbers
  1. public class CalibrateDAQViewPresenter :
  2. FunctionalTestModulePresenter<ICalibrateDAQView>
  3. {
  4.    private bool _stopping = false;
  5.    private bool _stopped = false;
  6.    private static readonly object _lockObject = new object();
  7.    protected override void Dispose(bool disposing)
  8.    {
  9.        // let the polling thread exit
  10.        lock (_lockObject)
  11.        {
  12.            _stopping = false;
  13.            while (_stopped == false) ;
  14.         }
  15.        base.Dispose(disposing);
  16.    }
  17.    public void OnViewReady()
  18.    {
  19.        _startReadingData();
  20.    }
  21.    private void _startReadingData()
  22.    {
  23.        _stopped = false;
  24.        _stopping = false;
  25.        ThreadPool.QueueUserWorkItem(
  26.            delegate
  27.            {
  28.                _dataPoller();
  29.            }
  30.        );
  31.    }
  32.    private void _dataPoller()
  33.    {
  34.        while(true)
  35.        {
  36.            lock(_lockObject)
  37.           {
  38.                 if(_stopping)
  39.                {
  40.                     _stopped = true;
  41.                     return;
  42.                 }
  43.                 // do stuff and update view
  44.            }
  45.            Thread.Sleep(100);
  46.          }
  47.     }
  48. }
  49.  


Thanks for reading!

Aug 23 '06 #2
"Adam Clauss" <ca*****@tamu.eduwrote in message
news:12*************@corp.supernews.com...
Your code will deadlock upon Dispose. Dispose locks on _lockObject, but
does not release that lock until the thread has stopped. The thread on
the otherhand, requires that same lock in order to stop.
One solution to this - get rid of the stopped flag.
In Dispose, replace the while loop (waiting on stopped) with a call to:
Monitor.Wait(_lockObject)

That will actually release the lock (allowing the thread to acquire it).
Then, in _dataPoller(), replace the:
_stopped = true;
with a call to:
Monitor.Pulse(_lockObject);

Note: this assumes you are not elsewhere using the _stopped flag.
Consideration may have to be added if other's need this as well.

--
Adam Clauss
Aug 23 '06 #3
a: What bugs / errors? This doesn't actually demonstrate anything

b: you're using a static lock at the instance level, so sharing a lock
between all instances; probably not what you wanted

c: if this is talking to a WinForm UI you will need to .Invoke/.BeginInvoke
to the UI to get the UI updates to work

d: while (_stopped == false) ;

This might never exit, as _stopped isn't volatile, so it will probably be
cached in a register; secondly, it is hugely intensive; personally I'd do
something more like the following:

lock(_lockObject) {
while(!_stopped) {
Monitor.Wait(_lockObject);
}
}

And "_stopped = true;" would become:
_stopped = true;
Monitor.Pulse(_lockObject);

Marc
Aug 23 '06 #4
Oh, and re the subject "of this simple threading code"... I'm not sure that
such exists in this universe ;-p
Aug 23 '06 #5
Thank you for the help, Adam. I see the problems with the code and am
reworking it now to take your suggestions into consideration. I think I
might move the "thread stopping" logic out of the dispose method and handle
it elsewhere, possibly the Closing event.

thanks again,
Steve
"Adam Clauss" <ca*****@tamu.eduwrote in message
news:12*************@corp.supernews.com...
"Adam Clauss" <ca*****@tamu.eduwrote in message
news:12*************@corp.supernews.com...
>Your code will deadlock upon Dispose. Dispose locks on _lockObject, but
does not release that lock until the thread has stopped. The thread on
the otherhand, requires that same lock in order to stop.

One solution to this - get rid of the stopped flag.
In Dispose, replace the while loop (waiting on stopped) with a call to:
Monitor.Wait(_lockObject)

That will actually release the lock (allowing the thread to acquire it).
Then, in _dataPoller(), replace the:
_stopped = true;
with a call to:
Monitor.Pulse(_lockObject);

Note: this assumes you are not elsewhere using the _stopped flag.
Consideration may have to be added if other's need this as well.

--
Adam Clauss


Aug 24 '06 #6
Thanks for the tips Marc.

You and Adam have suggested similar solutions, that's always a good thing
;0)

Have a good one,
Steve
"Marc Gravell" <ma**********@gmail.comwrote in message
news:OR**************@TK2MSFTNGP03.phx.gbl...
a: What bugs / errors? This doesn't actually demonstrate anything

b: you're using a static lock at the instance level, so sharing a lock
between all instances; probably not what you wanted

c: if this is talking to a WinForm UI you will need to
.Invoke/.BeginInvoke to the UI to get the UI updates to work

d: while (_stopped == false) ;

This might never exit, as _stopped isn't volatile, so it will probably be
cached in a register; secondly, it is hugely intensive; personally I'd do
something more like the following:

lock(_lockObject) {
while(!_stopped) {
Monitor.Wait(_lockObject);
}
}

And "_stopped = true;" would become:
_stopped = true;
Monitor.Pulse(_lockObject);

Marc

Aug 24 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
by: Ben Hanson | last post by:
I have created an open source Notepad program for Windows in C++ that allows search and replace using regular expressions (and a few other extras). It is located at...
6
by: Daniel Rimmelzwaan | last post by:
I want to send a biztalk document to an aspx page, and I need to see some sample code, because I just can't make it work. I have a port with transport type HTTP, pointing to my aspx page, something...
2
by: Ford Prefect alias Armin | last post by:
Hello I have a Problem of understanding how IIS/ASPX Works..... Why can't to request run at the "same" time ?? I have a Simple ASPX Web Application. It has two Button.
0
by: Rick | last post by:
Hello, I'm six months into asp.net/c# and enjoying it. A couple weeks ago I needed to write a "simple" high performance counter, the short story is it turned into a mini project. Many lesson...
1
by: Rick | last post by:
Hello, I'm six months into asp.net/c# and enjoying it. I needed to code a "simple" high performance counter... a couple weeks later and a lot of learning I think I did it. Many lesson lessons...
17
by: Benny Raymond | last post by:
I have a thread that sleeps for 5 minutes once it's finished running a method and then it repeats itself if it's supposed to (bool = true). Prior to 2.0 I was able to resume the thread after...
29
by: Praki | last post by:
Greetings All, i think this is the right group to post this question. i am working on client server model. in this model the client is sending request in thousands in number. for example per...
3
by: vijaykumardahiya | last post by:
Dear Sir, I have two queries. First question is: I have a Html page. On which Have two buttons Submit and Issue. I want when I click on Sumit button request should be go to submit.jsp. and When I...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.