ReneeC

First of all, I hope that everyone who is interested joins in this conversation especially SJ, Carsten, Spotty, Andreas and Nobugz.

Experienced developers here often see new developers experiencing difficulty after calling Threading.Sleep and more experienced developers take issue with its use but rarely is there ever a comprehensive explanation for that. I thought I¡¯d start a thread on this with background as to why we say these things. First of all some background information is needed.

In Windows operating systems, when one runs a process, they are starting a process. A process is a contextual environment for a program and it will allow a program to call the things it needs to run. These aspects of a process are kept fairly transparent to a developer but a process has properties external and internal to it. Externally, a process needs to send and receive messages so that controls (including forms) can behave as expected. Internally, transparent to basic developers there are message pumps for dispatching these messages to a users code and controls. A basic property that is expected of a process is that it be able to send and receive these messages which enable Windows to work. Threading.Sleep disables that ability. Often we see upset users who have strange problems who have just called Sleep. ¡°Sleep¡± disables a process ability to respond to anything internally or externally for the duration of Sleep call. Fundamentally then, a basic principle of a windows environment is that it is event driven and sleep disables the ability to process any and all events. Symptoms will be controls not working and forms not updating.

Often the new developer wants to wait on something and they call sleep and because the basic properties of a process have been altered, the new user see unexpected results.

Here is a design often seen here:

Private Sub PD()

While Not Condition ¡® User Loop

¡®Process Data
¡®Process Data
Sleep

If SomeCondition then Condition = true

End while

There is a strong desire on the part of the beginner to want to use sleep to manage basic design flaws which disables a programs ability to respond to internal messages and events. Beyond the process put into sleep states inability to respond to low Level GUI messages, the process also cannot respond to timers.

In other Operating systems there are states analogous to Sleep which is not as severe. A process can wake up to handle asynchronous execution so you might see designs analogous to this:

Subroutine Main()

Hibernate

End Sub

ASynchronousHandler1

End Sub

ASynchronousHandler2

End Sub

Such a program is immediately put to sleep and when there is the delivery of an asynchronous event, it¡¯s processed and the process goes back to sleep. The event could be a timer expiration or I/O completion etc. This architecture is useful for a program that handles something and then goes back to sleep. In other words, it¡¯s the basic design for a server. There is no analogous state in Dot Net and hence other techniques are used. This discussion would not be meaningful without offering models for the proper way code deal with issues like these:

Class Whatever

Protected Structure Wood

Public Arg1 as integer
Public Arg2 as Integer

End Structure

Private Wood1 as Wood

Protected friend withevents tmr as new System.Windows.Forms.Timer

Form1_load (ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Form1.load

Tmr.stop
tmr.interval = 250 ¡® one quarter of second interval

¡® Your load code

End Sub

Private Sub ProcessData(ArgA, Argb, ArgC)

Wood1 = new wood

Wood1.Arg1 = ArgA ¡® pack up data to process (Context)
Wood1.Arg2 = ArgB

Tmr.Start

End Sub

Private Sub Tmr_Tick (ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Tmr.Tic

Tmr.stop

¡®Unpack the data and process it

¡® From the data determine if we are finished

If Finshed then CompletionRoutine(wood1) else Tmr.Start

Return

End Sub

¡®

Private Sub CompletionRoutine(Wood1 as Wood)

¡®resume whatever you need to do

End Sub

End Class

This way the process never goes to sleep and remains responsive to users and data. With a little added complexity much is gained. I¡¯ve written over one hundred thousands lines of Dot net and have only used Sleep once. It was in a toolbar which moved itself. The effect I wanted was a gliding effect so I¡¯d move the toolbar a couple of pixels and sleep for a few milliseconds, schieving exactly the effect I wanted. But here is what often turns up in this forum:

Private Subroutine Foo()

WebBrowser.Nagivate(¡°www.foo.com¡±)
While Not WebBrowser.DocumentComplete

Sleep (50)

End While

¡®Continue processing

End Sub

This is REALLY BAD code. What if the URL is not there or it times out This process will never wakeup and sit like the rock of Gibraltar on your desktop until you kill it with Task Manager. Here, the user should have used an event:

Private Subroutine Foo()

WebBrowser.Nagivate(¡°www.foo.com¡±)

End Sub

Private Sub WebBrowser_NavigationComplete(ByVal sender As Object, _
ByVal e As System.NavigationEventArgs) _
Handles WbBrowser.NaVigationComplete

¡®Process the data and continue

End Sub

I¡¯ve come to see calling Threading.Sleep is having strayed into a fundamental design error, the possibility that a developer does not understand event handlers or they have missed a control or a component's events.




Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

js06

I just wanted to say thank you reneec

I really appreciate the explanation, i would really like to see more info on other points as well.

So many times i see - don't do this or don't do that. And the answer although really long, does not quite explain why.

And that may also be because the answer is over out heads.

This thread is a perfect example for many: it shows you what you shouldn't do and now here is how you should do it.

And why not to do it is explained very well.

And even better it has "Real World" examples.

Wonderful

Many times i feel like the knowledge that you more experienced programmers have is just sitting idle and teased by throwing simple code bits at us. Which many times that's what were askin for. And even though it gets you to the next point, many don't even know how or why it works. It just does. And i see the frustration all the more experienced have when us beginners just don't get it. Even though the answer you gave is the right one, we are still looking for the answer even though you gave it because we just don't understand how to put it together.

Thanks again, hope to see more.






Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

ReneeC

Hi JS06,

Perhaps this thread may give us a chance to talk about more than just Sleep I¡¯m a Crone meaning I¡¯m over fifty and I¡¯ve been a Crone for ten years now. That doesn¡¯t mean much other than I¡¯ve had a chance to acquire a historical perspective after seeing generational differences. I¡¯ve often wondered about what technology has done for us because we¡¯ve produced a generation who looks toward instant gratification. Beyond the wider social commentary, this has to do with the frustrations you¡¯ve referred to and I think there get¡¯s to be a lot of frustration at times.

Sometimes I feel overwhelmed when I see someone come in take on some of the things they do. It¡¯s like, ¡°I just tasted my first cheeseburger at McDonalds and I really want to fix a Julia Childs seventeen course dinner.¡± If you look closely, there are an awful lot of fundamentals in cooking ala Julia Child¡¯s. I also stress fundamentals because you absolutely need to know them. You can¡¯t make a cheeseburger if you don¡¯t know what cheese is.

Needless to say there is an enormity of depth to know in all of this and I see where I shall be a student forever. But I will always have the fundamentals to fall back on when I¡¯m interpreting whatever is new in front of me. This is why I stress fundamentals such as datatypes. There¡¯s another secret I¡¯ve discovered. It¡¯s not the answers you have, it¡¯s the questions you can generate to find a meaningful answer.

Returning to the frustrations, you¡¯re right it has to be frustrating to get half way answers. But to get full answers on question could require a post as long as my first post each time someone asks the same question and yet we see sleep induced problems many times a week here. One cannot post an answer like that over and over. So the answer is discussions like this one that we can point to as many times as the question is asked which should reduce a lot of the frustrations at least I hope it should.

I¡¯ve tried to do the same for lessons on how to use the debugger. New developers often seem to be shy of the debugger. More experienced developers need to encourage it¡¯s use instead of message boxes. But yes¡­ I¡¯d love to see more of these discussions.

And JS06¡­ thank you!






Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

Carsten Kanstrup

Actually, I have been tempted to post a thread like this about the abused functions Sleep and CreateGraphichs, but from the opposite point of view!

Unlike many others, I do not regard these functions as bad design. It is correct that Sleep blocks the thread from which it is called, but if it is a background thread it doesn't matter. If it is the UI thread, things are not just black and white. By default, the UI thread has higher priority than background threads and thread pool threads, so Sleep may be necessary to allow a job on a low priority thread to finish. For example, if you want to change a serial port, you need to close the old port and open a new one. However, you must give the system time to close down the background thread for the old port before creating a new thread for the new port, and the easiest way to do this is to block the high priority UI thread temporary by means of Sleep! In a background thread you can also use Sleep(0) to release the CPU if you cannot utilize the rest of the time slot. Besides, Windoze is so slow that blocking the UI thread for e.g. 200 mS doesn't really matter. If you call Application.DoEvents() to empty the message queue before the Sleep command, nobody will notice, and you may save a lot of programming and resources (timers etc.). Besides ReneeC, you are a little wrong. Sleep will not block the process ability to do anything as you write - just the thread from which it is called. This makes quite a difference.

Now the cork is off the bottle - I do not regard CreateGraphics as bad design either. The true teaching is just to call Invalidate() every time just a single pixel has been changed and therefore redraw the entire form, which of course takes time and create flicker if you do not use double buffering. It is correct that Windows (unlike the old Amiga) is not intelligent enough to repaint a window automatically if it e.g. has been covered by another window, so you must have a handler for the Paint event, which can do this, but you may need to draw hundreds of pixels per second, but only act on the paint event very seldomly. Actually, the vertical bargraph thread http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1539826&SiteID=1 is a very good example of the two ways of doing things. As Albert Einstein says: Everything should be made as simple as possible, but not simpler!

So my point is: It is OK to use all functions - you should just know what you are doing!

ReneeC

Your debugger thread was excellent, but much too fast digged down in the archive. Unfortunately, this forum does not have a place to put links to useful knowledge. I have also answered the same questions over and over again about the serial port - the only thing I really know something about in VB. Therefore, I have put all my knowledge on the knowledgebase on our homepage http://www.innovatic.dk/knowledg.htm. If you can rewrite your thread in one article suitable for a knowledgebase, I can put it in our's if you cannot find a better, more software oriented place to put it. Our knowledgebase primary focus on process control.





Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

asalcedo

Renee,

The idea that the Dot Net environment is event driven is, conceptually, very clear and powerful.

In practice, though, it is not so well behaved.

Your code,

Private Subroutine Foo()

WebBrowser.Nagivate(¡°www.foo.com¡±)

End Sub

Private Sub WebBrowser_NavigationComplete(ByVal sender As Object, _
ByVal e As System.NavigationEventArgs) _
Handles WbBrowser.NaVigationComplete

¡®Process the data and continue

End Sub

does not work for websites made of frames. The NavigationComplete or Document Complete events won't capture the final loading of the page.

You have to resort to sleeping the thread





Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

ReneeC

It's pretty well known that the webbrowser is not without problems. I've done a tabbed webbrowser in fact I'm typing on it now to you. It does frames fine and I promise you there is no Threading.sleep in the code. I've used it for a year now and and I've never seen a problem in it with framed pages.

Could you point me to a page where you say I'd have problems

It does absolutely fine on these pages:

http://victorian.fortunecity.com/brambles/4/frames/

http://hem.passagen.se/ceel/frames/frames.htm

Carsten,

I've written mainframe disk drivers so of course I understand multi-threading. Because I've written mainframe disk drivers which was also a Cutler operating system, I find the multithreading environment so restrictive that I have never used it. You might be right and who could object to sleep(0) but I really can't comment on that environment since I've never played in it. At any rate, here people are not having problems at that level.






Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

Carsten Kanstrup

ReneeC

The multithreading system of .NET is restrictive, but it has one advantage - it is very simple and easy to overlook. I truely believe that preemptive multithreading (time sliced) is something the devil has created when he was in a really bad mood, but the .NET version is really not that bad. Maybe you should start using it





Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

ReneeC

I'll use it when I need to calculate prime numbers from here to the moon. Given the dis/ease of threads being able to talk to controls not owned by that thread, I don't find the multithreading all that useable and have always been critical of that.

In all honestly if I ever had a situation where computation needs impacted the responsiveness of the UI, of course I'd use it, but that's not really the kind of computing that I do so it has not been an issues. I've used multithreading to create multi-core loads and good ones at that, but that's about all.

In anything but a single task computer with no OS, there is going to be timeslicing of some kind whether it's round robining or the servicing of hardware interrupts, it's going to happen and at the applications level it's transparent so I don't woory about it just as I didn't worry about it in my mainframe drivers because it's an inevitability.






Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

asalcedo

I am certainly not trying to dodge the question, but all the examples of pages with frames that give me problems with the documentcomplete event are behind passwords and thus, I cannot share. If I remember or find others that can be shared I will let you know.



Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

ReneeC

Please do. My browser is not without problems but they are in areas where there are known and reported bugs. I have never seen my browser act up in the the situations you describe.






Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

Carsten Kanstrup

ReneeC

The reason why I don't like preemptive task/thread swithing is because of the very low efficiency. Because you never know when you loose the CPU, all arguments for methods have to be transferred by value instead of by reference. What happens in today's computers is basically an endless data copying, which also leads to a serious fragmentation of the memory. The real payload is rather limited. Every time you want to do something, data is copied to and from the stack or heap, and each delegate need its own invoke methods to hold the arguments.

I have completely other visions for the future OS and computer world, which you can read more about on our homepage. If all tasks are atomic with a maximum execution time of 1 mS (100 uS for high priority) and everything takes place in the right order, you don't need to copy anything!





Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

ReneeC

" have completely other visions for the future OS and computer world, which you can read more about on our homepage."

My vision is not for a better OS because you can't have one on the Intel Architecture. Remember when Carl Sagan came out with "The Dragons of Eden" He talked about the reptillian brain in humans. Well from a hardware pov, we are still executing the remnants of 8086s. It's true.

Poor Cutler coming from a VAX Architecture for which he designed the instruction set, to the Intel platform. You speak of problems with context switching. The VAX did a context switch with one instruction designed for OS context switching. Memory on the Vax was "scatter/gather". That is to say that memory mamangement was a mixture of hardware and software where every process had a contiguous address space, user, supervisor, Executive and Kernal Stacks from the bottom to the top of four gigs. Certainly it had 32 software priorities and also hardware IPLs with their own address vectors and a basic and a most elegant instruction set of 400 instructions.

You won't have a good operating system until there is an equally good platform architecture for it to run on. The Vax did not have to copy anything to do a context switch, nor was there any fragmentation of memory.

Atomicity is a complex topic of course. Some instructions were atomic and some weren't. When you code in assembler you have to know what was what. There were also Movc3 and movc5 instructions used for both paging and buffer copies. There were non-atomic instructions if I remember correctly. But at high IPL's it didn't make any difference because you weren't going to be interrupted or if you were, your context would be there when the instruction resumed because of the stack architecture and the way the stack was used. Also at high IPLs you were working with non-paged pool. There was no paging.






Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

Carsten Kanstrup

ReneeC

I couldn't agree more with you about the hopeless Intel architecture (just see my answer to Tall Dude in the thread: "A question about programming languages in general" http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=1881611&SiteID=1) - that's why we also have a suggestion for a new microprocessor architecture on our homepage !

When I talk about atomic I just mean program parts with a maximum execution time of 1 mS - not single assembler instructions. I know that you really "burn" for operating systems, but try to ask yourself the question: What do you need an OS for You have only one CPU (normally), so at any time you can only run one part of your code. Contemporary execution is just an illusion. Suppose no routine was allowed to run for longer time than the interrupt latency, that is, approximately 1 mS, before it returns or waits for something (passive state). Then you did not have to cut any program (preemptive, time sliced switching) and you would not need any Deferred Procedure Calls. Everything would be reduced to a question about priorities. So instead of having multiple threads, which requires an enoumous amount of resources, you would only need two or three priority levels with a queue for each. All programs with the same priority could share the same thread. Even high priority interrupts could be executed as normal high priority jobs with a maximum execution time of e.g. 50 uS, so it would be much easier to write drivers as this could be done as any other program - just with a higher priority. If you don't put a routine on a queue if it is there already, it is guaranteed that all routines with the same priority gets a chance of running before any data can change again, so nothing needs to be transferred by value. So no need for threads, thread pools, endless data copying, Mbytes of stacks etc. - just two or three execution queues.

PS. I will be very busy until next week so I might not be able to continue this thread until then.





Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

asalcedo

Renee,

Can you give a fully working example of the following code:

Private Subroutine Foo()

WebBrowser.Nagivate(¡°www.foo.com¡±)

End Sub

Private Sub WebBrowser_NavigationComplete(ByVal sender As Object, _
ByVal e As System.NavigationEventArgs) _
Handles WbBrowser.NaVigationComplete

¡®Process the data and continue

End Sub

I have been trying the following but it does not work (I am using the IExplorer object, not the WebBrowser).

The event is fired, but it does not give time for the document to be loaded.

The NavigateComplete2 event works even worse, the event is not even fired.

Module Module1

Public Declare Function ShowWindow Lib "user32" (ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Integer

Public Const SW_SHOWMAXIMIZED As Integer = 3

Public WithEvents wb As New SHDocVw.InternetExplorer

Dim HTMLDoc As MSHTML.HTMLDocument

Dim iHTMLCol As MSHTML.IHTMLElementCollection

Sub Main()

ShowWindow(wb.HWND(), SW_SHOWMAXIMIZED)

wb.Visible = True

wb.Navigate("https://www.xyz.com")

End Sub

Private Sub wb_DocumentComplete(ByVal pDisp As Object, ByRef URL As Object) Handles wb.DocumentComplete

HTMLDoc = wb.Document

iHTMLCol = HTMLDoc.getElementsByTagName("input")

......

End Sub

End Module





Re: Visual Basic Express Edition Why To Not Use Threading.Sleep in Your Application

Andreas Johansson

Carsten Kanstrup wrote:

Actually, I have been tempted to post a thread like this about the abused functions Sleep and CreateGraphichs, but from the opposite point of view!

Unlike many others, I do not regard these functions as bad design. It is correct that Sleep blocks the thread from which it is called, but if it is a background thread it doesn't matter. If it is the UI thread, things are not just black and white. By default, the UI thread has higher priority than background threads and thread pool threads, so Sleep may be necessary to allow a job on a low priority thread to finish. For example, if you want to change a serial port, you need to close the old port and open a new one. However, you must give the system time to close down the background thread for the old port before creating a new thread for the new port, and the easiest way to do this is to block the high priority UI thread temporary by means of Sleep! In a background thread you can also use Sleep(0) to release the CPU if you cannot utilize the rest of the time slot. Besides, Windoze is so slow that blocking the UI thread for e.g. 200 mS doesn't really matter. If you call Application.DoEvents() to empty the message queue before the Sleep command, nobody will notice, and you may save a lot of programming and resources (timers etc.). Besides ReneeC, you are a little wrong. Sleep will not block the process ability to do anything as you write - just the thread from which it is called. This makes quite a difference.

You mention the changing of a serial port as an example, how long time do you sleep On my computer it may take 1 second and on my mothers 10 seconds. What is the proper time Windows and the .NET framework offers a lot of options to subscribe to various events, why not use those

Why would you make a background thread sleep If you need to wait for a hardware device to close down you should listen for that event and continue processing when that specific event occurs. If it is not a specific event in the .NET class you can usually give a callback procedure to be called when a specific event is raised or API finishes.

Making the UI thread call Sleep is very bad practice. You need to have the message loop responsive. This is also why you should use background threads/workers to do any heavy work.

Application.DoEvents() is not bad practice but you have to consider the possibility that during the call to Application.DoEvents() your application got a message to close down and must stop all processing in a clean way. This is a very common mistake that developers do when using Application.DoEvents(). You need to check if the application is closing down immediatly after all calls to it.

Thread.Sleep() is not a method you want to use and you should avoid it by all means. Making a thread sleep might have some usage in a device driver where you have to take into consideration for hardware needing to reach a stable state. As example when clicking a mouse button the actual switch in the mouse might bounce on the contact area and give mixed values during a fraction of a second and you can only rely on its value after a few microseconds.