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

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pawan Narula via DotNetMonster.com

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

    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_userspa ce As Int16
    Public Shared retval As Integer
    Public Shared th As System.Threadin g.Thread

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

    Public Shared Function CreateThread(By Val 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_userspa ce = arg2
    func = funcptr
    'th = New System.Threadin g.Thread(New System.Threadin g.ThreadStart(A ddressOf v_myclass.myfun ction))
    'th.Start()
    Dim mi_process_new_ invite As New MethodInvoker(A ddressOf v_myclass.myfun ction)
    ret = frmpresence_.In voke(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(ByR ef 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(InvokeRequir ed)
    retval = ts.CreateThread (AddressOf process_add_mem ber,
    CStr(abc.PtrToS tringAnsi(ap.st r)), 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.PtrToStrin gAnsi(ap.str)))
    Case ADD_GROUP
    add_member(CStr (abc.PtrToStrin gAnsi(ap.str)), GROUP)
    End Select
    End If
    Case ADD_NEW_SUBSCRI PTION
    /// 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.PtrToS tringAnsi(ap.st r)).

    create_APPEVENT _local(CONTACT, -1, CONTACT_ADD, -1, -1,CStr
    (abc.PtrToStrin gAnsi(ap.str)))
    Case NEW_SUBSCRIPTIO N
    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_inv ite,
    CStr(abc.PtrToS tringAnsi(ap.st r)), ap.chan)
    Else
    process_new_inv ite(CStr(abc.Pt rToStringAnsi(a p.str)), ap.chan)
    End If
    End Select
    Return retval
    End Function


    Private Function process_add_mem ber(ByVal remote As String, ByVal userspace As Int16) As Integer
    Select Case userspace
    Case ADD_CONTACT
    add_member(remo te)
    Case ADD_GROUP
    add_member(remo te, GROUP)
    End Select
    End Function


    Private Function process_new_inv ite(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.st ruct_remote

    frm_new_invite. set_invite_type (remote, chan)
    frm_new_invite. ShowDialog()
    remote_struct = frm_new_invite. nyget_remote()
    retval = remote_struct.u ser_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/Abu...0c583ff65b4f8c
    *************** *************** ***********
Working...