Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Threaded splash screen.

0 views
Skip to first unread message

elziko

unread,
Dec 5, 2002, 10:36:01 AM12/5/02
to
In the New sub of my program I open a form in another thread to act as a
splash screen whilst my application is opening up. The fact that it is
running on a seperate thread means the animated GIF on it is happily
animated.

So heres my function to open the form:

Public Sub SplashThreadEntryPoint()
Dim SplashScreen As New frmSplash()
Application.Run(SplashScreen)
End Sub

Heres my delegate:

Private SplashThreaded As New Threading.Thread(AddressOf
SplashThreadEntryPoint)

And i start by thread like this:

SplashThreaded.Start()

This works fine and the splash screen loads. At the end of my application's
Main Form's Load event I need to close the form and end the thread so I try
to:

SplashThreaded.Abort

This also works, however, when I actually exit my application I get the
following error:

The instruction at "0x77fcb1ad" referenced memory at "0x00b40010". The
memory could not be "read".

Can anyone tell me why this is happening? Is my application trying to close
a thread thats already closed? Should the thread close itself somehow?

Cheers,

elziko


Stephen Martin

unread,
Dec 5, 2002, 10:54:55 AM12/5/02
to
Inline...

"elziko" <elz...@NOTSPAMMINGyahoo.co.uk> wrote in message
news:#sCDGRHnCHA.2464@TK2MSFTNGP11...


> In the New sub of my program I open a form in another thread to act as a
> splash screen whilst my application is opening up. The fact that it is
> running on a seperate thread means the animated GIF on it is happily
> animated.
>
> So heres my function to open the form:
>
> Public Sub SplashThreadEntryPoint()
> Dim SplashScreen As New frmSplash()

Make SplashScreen a module level variable.

In declarations:
Private SplashScreen as frmSplash

Here:
SplashScreen = New frmSplash()

> Application.Run(SplashScreen)

Application.Run sets up the application's main message pump. You don't want
that here use:
SplashScreen.ShowDialog()

> End Sub
>
> Heres my delegate:
>
> Private SplashThreaded As New Threading.Thread(AddressOf
> SplashThreadEntryPoint)
>
> And i start by thread like this:
>
> SplashThreaded.Start()
>
> This works fine and the splash screen loads. At the end of my
application's
> Main Form's Load event I need to close the form and end the thread so I
try
> to:
>
> SplashThreaded.Abort

Never use thread.Abort unless you are recovering from an error condition. It
should be a last resort.

To Class frmSplash add:

Public Sub KillMe()
Me.Close
End Sub

In place of aborting your thread:
SplashScreen.KillMe

Marina

unread,
Dec 5, 2002, 10:54:55 AM12/5/02
to
What about having a variable that the application sets to True, to signify
it is done loading. The splash screen thread checks this periodically, and
when it sees it is True, it just returns from the Sub, so it just finishes
its run.

"elziko" <elz...@NOTSPAMMINGyahoo.co.uk> wrote in message
news:#sCDGRHnCHA.2464@TK2MSFTNGP11...

elziko

unread,
Dec 5, 2002, 11:27:10 AM12/5/02
to
Thanks I have changed the things you have suggested. I still have the probel
though. After commenting out all of this threading code I seem to still have
the same error message so I think this threading business was a red herring.
I've reposted my problem under a duffrent heading 'The memory could not be
"read" error' if you want to take a look!

Thanks,

elziko


Rockford Lhotka

unread,
Dec 5, 2002, 2:05:21 PM12/5/02
to
The basic flow should be this:

In your main form's code, start up a background thread and have it run a
method - say A.

In method A you create the splash form and display it. This method should
also put a reference to the splash screen into a variable that is accessible
to the main form's code.

At this point the splash screen is displayed, and it is running on the
background thread.

The main thread continues to initialize the application. When it is done, it
uses the splash form's Invoke method to safely tell the splash screen to
shut itself down.

When the splash screen shuts down, the background thread will automatically
terminate.

Note that the use of the Invoke method is _required_ to safely call a form
that is running on a different thread.

There is a complete example of how to do this in the 'VB.NET Solutions
Toolkit' book from Wrox Press.

--
Rockford Lhotka
Author of "Fast Track Visual Basic.NET"
ro...@lhotka.net http://www.lhotka.net


"elziko" <elz...@NOTSPAMMINGyahoo.co.uk> wrote in message
news:#sCDGRHnCHA.2464@TK2MSFTNGP11...

Stephen Martin

unread,
Dec 6, 2002, 6:50:56 AM12/6/02
to
Note that the use of the Invoke method is _not_ required to safely call the
Close method of a Form that is running on a different thread. The use of
Invoke is required for much(particularly the GUI elements) but by no means
all access to a Form created on a different thread


"Rockford Lhotka" <ro...@lhotka.net> wrote in message
news:#jYrPEJnCHA.1872@TK2MSFTNGP09...

Rockford Lhotka

unread,
Dec 7, 2002, 12:48:40 AM12/7/02
to
That may be true in practice. However, the documentation for the Form class
is quite clear that only Shared methods are thread-safe. All instance
methods (including Close) should be assumed to _not_ be thread safe.

Calling Close (or any other instance method) directly from a background
thread may (or may not) consistently work now, but could easily break in a
future version of .NET - Microsoft specifically isn't guaranteeing that such
a call is safe.

Good programming practice is to use Invoke.


--
Rockford Lhotka
Author of "Fast Track Visual Basic.NET"
ro...@lhotka.net http://www.lhotka.net


"Stephen Martin" <sma...@removethis.emsoft.andthis.ca> wrote in message
news:#tim41RnCHA.456@TK2MSFTNGP11...

Stephen Martin

unread,
Dec 7, 2002, 11:04:33 AM12/7/02
to
You appear to be confusing thread safety and 'apartment' threading. The
reason that you use Invoke when touching the GUI of a form from a different
thread is to marshal the call to the correct apartment not because the
method may or may not be thread-safe(though apartment specific calls are by
definition not thread-safe). Thread-safety is a synchronization issue.

If I have a class deriving from System.Windows.Forms.Control with a module
level variable m_nSomeInteger and it has a method:

Public Sub DoSomethingSilly()
m_nSomeInteger += 5
End Sub

This method is not thread-safe but that doesn't mean that I need to use
Invoke to call it from a non-owner thread.

Microsoft can, in theory, make a breaking change to any method of any class.
Microsoft guarantees that an assembly will work with the framework version
with which it was compiled nothing more.

You may feel that using Invoke when accessing any method in a class that
derives from Control is a good programming practice and depending on
circumstances(project, team, etc.) I might agree with you but it is
certainly not required and in my opinion it doesn't rate a blanket good
programming practice label either.


"Rockford Lhotka" <ro...@lhotka.net> wrote in message

news:e7EjRQbnCHA.2408@TK2MSFTNGP10...

0 new messages