vb.net 2008 - terminate a function not the whole program

W

Wal

I have written a program which lists all possible English words from a
set of letters. Trouble is if you enter something over 8 letters long
the [swap letters around then verify word] function can go on for
several minutes.

I've put in a progress bar and word counter to show the program is busy
working in the background but they may still want to exit early (without
using Windows End Task).

I can't figure out how to interrupt it because all resources are busy so
clicking a Cancel button wont get any attention until the process ends.

Perhaps if the process can check for user input at regular intervals eg.
the Esc key has been pressed?
 
A

Armin Zingler

Wal said:
I have written a program which lists all possible English words from
a set of letters. Trouble is if you enter something over 8 letters
long the [swap letters around then verify word] function can go on
for several minutes.

I've put in a progress bar and word counter to show the program is
busy working in the background but they may still want to exit early
(without using Windows End Task).

I can't figure out how to interrupt it because all resources are
busy so clicking a Cancel button wont get any attention until the
process ends.

Perhaps if the process can check for user input at regular intervals
eg. the Esc key has been pressed?

My personal basic rule is: If you want to do two things at a time (keep UI
responsive and do the calculcations), use two Threads. Look for multi
threading in the documentation. Be aware that multi threading is an advanced
programming technique. Have a look at the BackgroundWorker class that some
people find helpful. I posted the following example few days ago: (in Sub
OnDoWork, replace "Do..Loop" by your own code; and don't forget to check the
BGW's CancellationPending property in your code, too.)

Imports System.ComponentModel

Public Class Form1

Private Sub Form1_Load( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles MyBase.Load

Dim bgw As New BackgroundWorker

bgw.WorkerSupportsCancellation = True
AddHandler bgw.DoWork, AddressOf OnDoWork
AddHandler bgw.RunWorkerCompleted, AddressOf OnWorkerCompleted

Debug.Print("Starting worker")
bgw.RunWorkerAsync()

Debug.Print("Waiting 5 seconds...")
Threading.Thread.Sleep(5000)
Debug.Print("Cancelling worker")
bgw.CancelAsync()

End Sub

Private Sub OnDoWork( _
ByVal sender As Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs)

Debug.Print("Start OnDoWork")
Do
Threading.Thread.Sleep(250)
Loop Until DirectCast(sender, BackgroundWorker).CancellationPending
Debug.Print("End OnDoWork")

End Sub

Private Sub OnWorkerCompleted( _
ByVal sender As Object, _
ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)

Debug.Print("Worker completed")

End Sub


End Class



Armin
 
M

Mike Williams

I have written a program which lists all possible English
words from a set of letters. Trouble is if you enter
something over 8 letters long the [swap letters around
then verify word] function can go on for several minutes.

Wow! That's a very long time. Perhaps you might like to look again at your
algorithm? You should be able to get it running very much faster than that.
Actually I don't use vb.net myself, being a VB6 programmer, and I'm just
really "nosing around" in here but I imagine that vb.net would not be very
much slower than VB6 when performing this sort of task? I don't know how
many words your dictionary contains, but just to give you an idea of what I
think you should be aiming for my own VB6 program, which is actually for use
in Scrabble and which does not therefore contain any words longer than 15
characters, finds 528 valid English words using the characters REITERATING
from a dictionary of 267,751 words in less than half a second, and that
includes the time taken to display the results in a listbox in word lenght
and alphabetical order.

I can't figure out how to interrupt it because all resources
are busy so clicking a Cancel button wont get any attention
until the process ends.

In VB6 we would use a DoEvents for allowing things like button clicks under
such circumstances in a single thread. Does vb.net have anything similar, or
can you perhaps run the button code in a different thread (I don't use
multiple threads myself so I can't really help you there).
I've put in a progress bar and word counter to show the
program is busy working in the background . . .

Personally I would forget about the progress bar and concentrate on your
algorithm. If you get that right then a progress bar will not be needed.

Mike
 
C

Clive Lumb

Wal said:
I have written a program which lists all possible English words from a set
of letters. Trouble is if you enter something over 8 letters long the [swap
letters around then verify word] function can go on for several minutes.

I hope that you are not checking each combination against the dictionary? If
you are doing this then it is obvious that it will take forever. It will be
faster if you check every word (of 8 letters or less) in the dictionary
against the 8 letter word - at least then you are only dealing with words
that exist.
 
F

Family Tree Mike

Though not answering directly the original question, someone had a similar
task some time ago on one of the boards. The recommended solution was to
keep a dictionionary that had a key be the string of letters to lookup
(sorted alphabetically), and then store a list of words from your input word
list into the dictionary by letters they use. For example:

Dictionary <string, list<string>> DICTIONARY;

CAR is stored under DICTIONARY ["ACR"].
ARC is also stored under DICTIONARY ["ACR"].
RACE is stored under DICTIONARY ["ACER"].

You can quickly fill the dictionary on load, and the lookups should be quick.
 

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