Invoke Method

S

S Shulman

Hi

I am looking for a method that allows calling a method that will be executed
by the main application thread bu will be called from any thread that I
create manually.
(I think that technically it is similar to sending a message to the
program)

I tried the Invoke method but it seem to work from the calling thread

Thank you,
Shmuel Shulman
 
C

Cor Ligthert

S Shulman

I made this today because I was curious about someting, maybe can you use
it.

\\\Needs a form with a listbox on it
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim myQ As New Queue
Dim myreadDb As New readDatabase(myQ)
Dim MyThr As New System.Threading.Thread(AddressOf myreadDb.Read)
MyThr.Start()
Me.Show()
Do Until myreadDb.ready AndAlso myQ.Count = 0
SyncLock myQ.SyncRoot
If myQ.Count > 0 Then
Me.ListBox1.Items.Add(myQ.Dequeue)
Me.ListBox1.SelectedIndex = ListBox1.Items.Count - 1
Me.ListBox1.Show()
End If
End SyncLock
Loop
End Sub
End Class
Public Class readDatabase
Private MyQ As Queue
Friend ready As Boolean
Public Sub New(ByVal pMyQ As Queue)
MyQ = pMyQ
End Sub
Friend Sub Read()
Dim fi As New IO.FileInfo("c:\test1\db3.mdb")
If Not fi.Exists Then
Dim db As New CreateDB
End If
Dim conn As New
OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
" Data Source=C:\Test1\db3.mdb;User
Id=admin;Password=;")
Dim cmd As New OleDb.OleDbCommand("select count(*) from Test", conn)
conn.Open()
Dim count As Integer = CInt(cmd.ExecuteScalar())
cmd.CommandText = "Select * from Test"
Dim drdr As OleDb.OleDbDataReader
drdr = cmd.ExecuteReader()
While drdr.Read()
SyncLock MyQ.SyncRoot
MyQ.Enqueue(drdr.GetInt32(1))
End SyncLock
End While
ready = True
drdr.Close()
conn.Close()
End Sub
End Class
Friend Class CreateDB
Public Sub New()
Dim catNewDB As New ADOX.Catalog
Dim fi As New IO.FileInfo("c:\test1\db3.mdb")
If fi.Exists Then
If MessageBox.Show("Delete?", "Existing File db3.mdb", _
MessageBoxButtons.YesNo) = DialogResult.Yes Then
fi.Delete()
Else
Exit Sub
End If
End If
catNewDB.Create("Provider=Microsoft.Jet.OLEDB.4.0;" & "Data
Source=C:\test1\db3.mdb")
Dim conn As New
OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
" Data Source=C:\Test1\db3.mdb;User Id=admin;Password=;")
Dim cmd As New OleDb.OleDbCommand("CREATE TABLE Test ( " & _
"Gid uniqueidentifier, " & _
"NextN int, " & _
"CONSTRAINT [pk_Gid] PRIMARY KEY (Gid)) ", conn)
conn.Open()
cmdExecute(cmd)
cmd.CommandText = "INSERT INTO Test (Gid, NextN) VALUES (?, ?)"
cmd.Parameters.Add _
(New OleDb.OleDbParameter("", OleDb.OleDbType.Guid))
cmd.Parameters.Add _
(New OleDb.OleDbParameter("", OleDb.OleDbType.Integer))
For i As Integer = 0 To 20000
cmd.Parameters(0).Value = Guid.NewGuid
cmd.Parameters(1).Value = i
cmdExecute(cmd)
Next
conn.Close()
End Sub
Private Sub cmdExecute(ByVal cmd As OleDb.OleDbCommand)
Try
cmd.ExecuteNonQuery()
Catch ex As OleDb.OleDbException
MessageBox.Show(ex.Message, "OleDbException")
Exit Sub
Catch ex As Exception
MessageBox.Show(ex.Message, "GeneralException")
Exit Sub
End Try
End Sub
End Class
///
I hope this helps a little bit?

Cor
 
G

Guest

Cor, when trying your code, I get a compile Error on the line where you
compare the messagebox result to = DialogResult.Yes. The Compile Error is
"Reference to a non-shared member requires an object reference". The
Compiler is complaining about the DialogResult.Yes as it's underlined as
being the problem.

Cor Ligthert said:
S Shulman

I made this today because I was curious about someting, maybe can you use
it.

\\\Needs a form with a listbox on it
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim myQ As New Queue
Dim myreadDb As New readDatabase(myQ)
Dim MyThr As New System.Threading.Thread(AddressOf myreadDb.Read)
MyThr.Start()
Me.Show()
Do Until myreadDb.ready AndAlso myQ.Count = 0
SyncLock myQ.SyncRoot
If myQ.Count > 0 Then
Me.ListBox1.Items.Add(myQ.Dequeue)
Me.ListBox1.SelectedIndex = ListBox1.Items.Count - 1
Me.ListBox1.Show()
End If
End SyncLock
Loop
End Sub
End Class
Public Class readDatabase
Private MyQ As Queue
Friend ready As Boolean
Public Sub New(ByVal pMyQ As Queue)
MyQ = pMyQ
End Sub
Friend Sub Read()
Dim fi As New IO.FileInfo("c:\test1\db3.mdb")
If Not fi.Exists Then
Dim db As New CreateDB
End If
Dim conn As New
OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
" Data Source=C:\Test1\db3.mdb;User
Id=admin;Password=;")
Dim cmd As New OleDb.OleDbCommand("select count(*) from Test", conn)
conn.Open()
Dim count As Integer = CInt(cmd.ExecuteScalar())
cmd.CommandText = "Select * from Test"
Dim drdr As OleDb.OleDbDataReader
drdr = cmd.ExecuteReader()
While drdr.Read()
SyncLock MyQ.SyncRoot
MyQ.Enqueue(drdr.GetInt32(1))
End SyncLock
End While
ready = True
drdr.Close()
conn.Close()
End Sub
End Class
Friend Class CreateDB
Public Sub New()
Dim catNewDB As New ADOX.Catalog
Dim fi As New IO.FileInfo("c:\test1\db3.mdb")
If fi.Exists Then
If MessageBox.Show("Delete?", "Existing File db3.mdb", _
MessageBoxButtons.YesNo) = DialogResult.Yes Then
fi.Delete()
Else
Exit Sub
End If
End If
catNewDB.Create("Provider=Microsoft.Jet.OLEDB.4.0;" & "Data
Source=C:\test1\db3.mdb")
Dim conn As New
OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
" Data Source=C:\Test1\db3.mdb;User Id=admin;Password=;")
Dim cmd As New OleDb.OleDbCommand("CREATE TABLE Test ( " & _
"Gid uniqueidentifier, " & _
"NextN int, " & _
"CONSTRAINT [pk_Gid] PRIMARY KEY (Gid)) ", conn)
conn.Open()
cmdExecute(cmd)
cmd.CommandText = "INSERT INTO Test (Gid, NextN) VALUES (?, ?)"
cmd.Parameters.Add _
(New OleDb.OleDbParameter("", OleDb.OleDbType.Guid))
cmd.Parameters.Add _
(New OleDb.OleDbParameter("", OleDb.OleDbType.Integer))
For i As Integer = 0 To 20000
cmd.Parameters(0).Value = Guid.NewGuid
cmd.Parameters(1).Value = i
cmdExecute(cmd)
Next
conn.Close()
End Sub
Private Sub cmdExecute(ByVal cmd As OleDb.OleDbCommand)
Try
cmd.ExecuteNonQuery()
Catch ex As OleDb.OleDbException
MessageBox.Show(ex.Message, "OleDbException")
Exit Sub
Catch ex As Exception
MessageBox.Show(ex.Message, "GeneralException")
Exit Sub
End Try
End Sub
End Class
///
I hope this helps a little bit?

Cor
 
C

Cor Ligthert

Dennis,

I forgot to write as well that it needs a reference to a reference to COM
adox ext 2.x for dll and security
However I cannot force the error you have.

Maybe is there with pasting an _ gone wrong that happens sometimes.

Cor
 
C

Cor Ligthert

Dennis/Shulman,

I remade the sample, I think that this one is nicer as sample

\\\Needs a form with a listbox on it
Private myQ As New Queue
Dim myreadDb As New readData(myQ)
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim tim As New System.Windows.Forms.Timer
AddHandler tim.Tick, AddressOf tickselapsed
tim.Interval = 600
tim.Enabled = True
Dim MyThr As New System.Threading.Thread(AddressOf myreadDb.Read)
MyThr.Start()
End Sub
Public Sub tickselapsed(ByVal sender As Object, ByVal e As System.EventArgs)
DirectCast(sender, Timer).Enabled = False
Do Until myQ.Count = 0
SyncLock myQ.SyncRoot
If myQ.Count > 0 Then
Me.ListBox1.Items.Add(myQ.Dequeue)
Me.ListBox1.SelectedIndex = ListBox1.Items.Count - 1
Me.ListBox1.Show()
End If
End SyncLock
Loop
If myreadDb.ready = False Then
DirectCast(sender, Timer).Enabled = True
End If
End Sub
End Class
Public Class readData
Private MyQ As Queue
Friend ready As Boolean
Public Sub New(ByVal pMyQ As Queue)
MyQ = pMyQ
End Sub
Friend Sub Read()
For i As Integer = 0 To 500
SyncLock MyQ.SyncRoot
MyQ.Enqueue(i)
Threading.Thread.Sleep(CInt(i / 10))
End SyncLock
Next
ready = True
End Sub
End Class
///

I hope this helps?

Cor
 
G

Guest

I got all of you code to work ok but had to work around the DialogResult.Yes.
I tried just putting a statement in the Load Event to the effect dim r as
Dialogresult = DialogResult.Yes it compiled ok. However, if I put this same
statement in any of the classes, I get the same compile error with
DialogResult.Yes underlined. I've had some trouble in the past with things
like this with VB.2003 but they've been erratic.
 
G

Guest

Cor, it's very strange. I tried putting the statement " Dim r As
DialogResult = DialogResult.Yes" in some of my other applications and found
that I could put it in any main class ok but if I tried the following in a
sub class I get the same compile Error:

Public Class myfirstclass
Dim r As DialogResult = DialogResult.Yes (works ok here)
......
......
Friend Class mysubClass
Dim r As DialogResult = DialogResult.Yes (I get the compile error
here)
........
End Class

End Class
 
S

S Shulman

Thanks Cor,
I have implemented a similar solution which works perfectly
But for the sake of the programming style I wanted to use the message queue
of windows I wonder if it is possible with VB.NET

Shmuel
 
G

Guest

I added a reference to System.Windows.Forms as well as an Imports
System.Windows.Forms to the module and still get the same results.
 
G

Guest

This seems to work ok in any Class in your example.

Dim r As DialogResult = System.Windows.Forms.DialogResult.Yes
 

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

Similar Threads


Top