XMLpitstop.com   |  VBnetexpert.com   |  Community Credit  
 
 
Pitstop Search:  
in
 
Sign in | Join | Help
 
 
  Blog
    Home  
 
  Entries By Date
 
<November 2008>
SunMonTueWedThuFriSat
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456
 
 
  Blog Categories
   
 
  Archives
    December 2009 (2)  
    October 2009 (1)  
    September 2009 (1)  
    August 2009 (2)  
    July 2009 (2)  
    June 2009 (1)  
    May 2009 (1)  
    February 2009 (1)  
    December 2008 (1)  
    November 2008 (3)  
    September 2008 (3)  
    August 2008 (3)  
    June 2008 (4)  
    May 2008 (2)  
    April 2008 (3)  
    March 2008 (3)  
    February 2008 (5)  
    December 2007 (4)  
    November 2007 (1)  
    October 2007 (3)  
 
  Syndication
    RSS  
    Atom  
    Comments RSS  
  .NET Flea Market  
 

Your Code Is Very Important To Us, Please Continue To Wait...

It was asked of me once: Why isn't my "please wait" form doing anything?  The form had an animation, but the animation never moved.  The main form code would show the "please wait" form, run some code, then hide the "please wait" form.  As it turned out, the "please wait" form was being blocked by a database call and some other stuff in the main form.  There was never a chance for a DoEvents or redraw or anything.

The quick answer is, you have to show the other form in another thread, so it can operate freely and redraw itself.  The longer answer is, you have to deal with threading.

Threading is very easy in VB.NET, but some people want answers, not lessons, so I ended up writing this quick class to show a form in another thread.  It's pretty simple.  You instantiate the class by passing in an instance of your "please wait" form , then call show(), do your work, then call hide().  Like so:

Dim f as New BackgroundForm(new frmWait)

f.Show()
' Do some stuff
f.Hide()

Only one caveat: you can't have the variable for the BackgroundForm class at the class level.  It must be declared, instantiated, and used in the same method.  Otherwise, you will get Cross-Threading errors.

So, here's the class you can use for yourself, if you prefer answers to lessons.

 
Public Class BackgroundForm
    Dim displayForm As Form
    Dim t As System.Threading.Thread
    Dim isActive As Boolean
    Shared lockObject as New Object

    Public Sub New(ByVal f As Form)
        displayForm = f
    End Sub

    Public Sub Show()
        t = New System.Threading.Thread(AddressOf ShowForm)
        t.IsBackground = True
        t.Start()
        isActive = True

    End Sub

    Public Sub Hide()
        isActive = False
    End Sub

    Private Sub ShowForm()
        displayForm.Show()

        Do While isActive AndAlso displayForm.Visible
            System.Threading.Thread.Sleep(100)
            SyncLock lockObject
            Application.DoEvents()
            End SyncLock
        Loop

    End Sub

End Class

I made a slight change to the code to protect against thread stomping.  If you have an animated GIF in your "please wait" form, and you have a more than one "please wait" form active at once, there is the chance you will get a "object is in use elsewhere" error.  This happens when the image for the current form is being changed - in the DoEvents - but another form is being closed/disposed, taking the same image with it.

By wrapping the DoEvents in a SyncLock that is shared among all instances, this is prevented.  I couldn't get the error to happen unless I opened over 20 windows and had them closing at scheduled times, but your luck may be worse.

Published Nov 25 2008, 10:41 PM by anachostic
Filed under: ,
Comments

No Comments

About anachostic

That's me. Seek and ye shall find.
 
 
Copyright © . All Rights Reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems