Multi-Threading Problem in VB.NET - Cannot call Invoke or InvokeAsync

  • Thread starter Pawan Narula via DotNetMonster.com
  • Start date
P

Pawan Narula via DotNetMonster.com

hi all,

i'm using VB.NET and trying to code for contact management in a tree. all my contacts r saved in a text file and my C dll reads them one by one and sends to VB callback in a sync mode thread. so far so good. all contacts r added properly.

now when another login adds me in his contact, i recv a subscription, so i popup a form and ask for accept/reject. this all happens in a separate thread. popup form gets opened and choice is travelled back to C Dll. all in sync still. on accept C dll tells UI to add the new subscription. at this point i get an error. Cannot call Invoke or InvokeAsync on a control until the window handle has been created. I call the same method with which i added my initial contacts from file.

this is when i check for if (InvokeRequired) then. if i dont put this check, i get another error saying cannot build control from a different thread. parent and child thread problem. so solve this i used control.invoke/ InvokeRequired. this gives me a new error as Cannot call Invoke or InvokeAsync on a control until the window handle has been created.

how to create and use this handle here. pl. advise.

my code is like -

//////this is a class to allow VB Invoke/Threads accept multiple args
Public Class Thread_string
Public Delegate Function Start(ByVal str As String, ByVal chan As Int16) As Integer
Public Shared func As Start
Public Shared str_ As String
Public Shared chan_or_userspace As Int16
Public Shared retval As Integer
Public Shared th As System.Threading.Thread

Public Class myclass_
Public Sub myfunction()
Dim ret As Integer
retval = func(str_, chan_or_userspace)
'th.Abort()
End Sub
End Class

Public Shared Function CreateThread(ByVal funcptr As Start, ByVal arg As String, ByVal arg2 As Int16) As Integer
Dim v_myclass As New myclass_()
Dim frmpresence_ As New FrmPresence()
Dim ret As Integer
str_ = arg
chan_or_userspace = arg2
func = funcptr
'th = New System.Threading.Thread(New System.Threading.ThreadStart(AddressOf v_myclass.myfunction))
'th.Start()
Dim mi_process_new_invite As New MethodInvoker(AddressOf v_myclass.myfunction)
ret = frmpresence_.Invoke(mi_process_new_invite)
Return retval
End Function
End Class
/////////////////////////////////////


////////////////CALLBACK////////////////
/// ap is a Struct type that i use to send data from C dll to VB and vice-versa.

Private Function my_callback(ByRef ap As APPEVENT) As Integer
Dim abc As System.Runtime.InteropServices.Marshal
Dim str As String
Dim retval As Integer = Success

Select Case ap.data1
Case CONTACT_START
Dim ts As New Thread_string()
If (InvokeRequired) Then
///// when case 2 tells C dll to add contact
///(simulates the same event when UI adds a contact on
///its own. control comes to this If(InvokeRequired)
retval = ts.CreateThread(AddressOf process_add_member,
CStr(abc.PtrToStringAnsi(ap.str)), ap.userspace)
/////// Here lies the current error. Handle required.
Else
///// at startup this else part is executed. this works fine.
/// without any error. as C dll sends all in sync.
Select Case ap.userspace
Case ADD_CONTACT
add_member(CStr(abc.PtrToStringAnsi(ap.str)))
Case ADD_GROUP
add_member(CStr(abc.PtrToStringAnsi(ap.str)), GROUP)
End Select
End If
Case ADD_NEW_SUBSCRIPTION
/// This is telling the C dll to add a contact. Infact C dll had send this CASE info based on case-3's user choice which opened another accept/reject invite form. UI then simulates the same process of adding a contact as did when UI adds a contact, so then C dll will in turn ask UI to add contact thru case 1- CONTACT_START. UI sends this info to C when adding a contact. this time last arg is what UI recd thru C. where as while adding contact on its own, UI sends the user entered text to C in place of CStr(abc.PtrToStringAnsi(ap.str)).

create_APPEVENT_local(CONTACT, -1, CONTACT_ADD, -1, -1,CStr
(abc.PtrToStringAnsi(ap.str)))
Case NEW_SUBSCRIPTION
Dim ts As New Thread_string()
If (InvokeRequired) Then
////always get in here. never in else part. done smoothly. no
////////error. fom gets opened and choice sent to dll thru retal.
retval = ts.CreateThread(AddressOf process_new_invite,
CStr(abc.PtrToStringAnsi(ap.str)), ap.chan)
Else
process_new_invite(CStr(abc.PtrToStringAnsi(ap.str)), ap.chan)
End If
End Select
Return retval
End Function


Private Function process_add_member(ByVal remote As String, ByVal userspace As Int16) As Integer
Select Case userspace
Case ADD_CONTACT
add_member(remote)
Case ADD_GROUP
add_member(remote, GROUP)
End Select
End Function


Private Function process_new_invite(ByVal remote As String, ByVal chan As Int16) As Integer
Dim retval As Integer
Dim frm_new_invite As New FrmNewInvite()
Dim remote_struct As FrmNewInvite.struct_remote

frm_new_invite.set_invite_type(remote, chan)
frm_new_invite.ShowDialog()
remote_struct = frm_new_invite.nyget_remote()
retval = remote_struct.user_choice
frm_new_invite.nydispose_form()
/////retval is returned properly............. runs fine.
End Function

pl. help.......

pawan

*****************************************
* This message was posted via http://www.dotnetmonster.com
*
* Report spam or abuse by clicking the following URL:
* http://www.dotnetmonster.com/Uwe/Abuse.aspx?aid=2a9813111e7844b9980c583ff65b4f8c
*****************************************
 

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