|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
VB.NET: RasDial + CallBacks + throwing events = frozen UI?up until just recently, i was fairly sure i'd implemented a RasDial class in VB.NET complete with a callback to get updated status. from this wrapper, when i throw an event back to the calling program, i can console.writeline the state successfully. but as soon as i replace that line with updating the UI, the program freezes, and execution halts. no exceptions are thrown or anything (i've got the line in a try...catch block, but nothing happens), the app just freezes. in fact, if i just mouseover the line that causes the problem (in this case, it's just a simple Me.Text of a form that's calling my object), the program freezes. what's amusing is that i can successfully observe and return Me.Left...i imagine it has something to do with the RasDial occurring in a separate thread...but it's not working regardless. any help would be appreciated, thanks in advance. relevant sample code: --- 'in a class 'The callback function for obtaining updated ras states Private mRasCallBack As RasDialCallBack = AddressOf RasDialFunc Public Function Dial(ByVal Parameters As RASDIALPARAMS) As IntPtr Try 'Declare return value Dim lReturn As Int32 'Declare handle for RAS dial attempt Dim lHandle As IntPtr 'Reset flag that controls whether or not we're done dialing mRasDone = False 'Start dialing lReturn = modRASAPI.RasDial(IntPtr.Zero, Nothing, Parameters, 0, mRasCallBack, lHandle) 'See if an error occurred If lReturn <> 0 Then 'Get the error message Dim lErrString As String = modRASAPI.DecodeRASErrorNumber(lReturn) 'Throw the error Throw New Exception(lErrString) End If 'Return the handle Dial = lHandle Catch ex As Exception Throw ex End Try End Function Private Function RasDialFunc(ByVal unMsg As Integer, ByVal rasconnstate As Integer, ByVal dwError As Integer) As Integer Try 'Get the new state Dim lState As RasConnState = rasconnstate 'Throw a state changed event RaiseEvent StateChanged(lState, GetConStateSTR(lState)) 'See if we're either connected or disconnected Select Case lState Case modRASEnums.RasConnState.Connected 'Raise a done message ThrowDoneEvent(True, 0, "") Case modRASEnums.RasConnState.Disconnected 'Raise a done message ThrowDoneEvent(True, 0, "") End Select 'See if an error occurred If dwError <> 0 Then 'First we need to determine what the error is Dim lErrorMessage As String Try 'Attempt to decode the error number lErrorMessage = modRASAPI.DecodeRASErrorNumber(dwError) Catch ex As Exception 'Assume the error message, if there was one lErrorMessage = ex.Message End Try 'Raise a done message ThrowDoneEvent(False, dwError, lErrorMessage) End If Catch ex As Exception Throw ex End Try End Function --- 'in the calling program Private Sub mRAS_StateChanged(ByVal CurrentState As pdsRAS.modRASEnums.RasConnState, ByVal CurrentStateStr As String) Handles mRAS.StateChanged Try 'this line works, and i can see the updated state in the console Console.WriteLine(CurrentState) 'this line does not work, and the app halts Me.Text = CurrentState Catch ex As Exception Stop End Try End Sub bhc wrote:
Show quoteHide quote > all- More then likely you are right - it is occuring on a separate thread.> > up until just recently, i was fairly sure i'd implemented a RasDial > class in VB.NET complete with a callback to get updated status. from > this wrapper, when i throw an event back to the calling program, i can > console.writeline the state successfully. but as soon as i replace > that line with updating the UI, the program freezes, and execution > halts. no exceptions are thrown or anything (i've got the line in a > try...catch block, but nothing happens), the app just freezes. in > fact, if i just mouseover the line that causes the problem (in this > case, it's just a simple Me.Text of a form that's calling my object), > the program freezes. what's amusing is that i can successfully > observe and return Me.Left...i imagine it has something to do with the > RasDial occurring in a separate thread...but it's not working > regardless. You should check the Me.InvokeRequired propertie in the callback - if it is true, then you need to call Me.Invoke so that the call is marshaled to the UI thread... -- Tom Shelton [MVP] that's what i was afraid of...perhaps you could expand a little bit on
Invoking, as it's definitely not me strong suit... what i gather, is that i need to have a Sub that updates the form text, declare a Delegate that has the same signature, and a variable of the Delegate type that has an AddressOf pointing to the Sub. what i have right now.... Private Delegate Sub DelUpdateTextCallBack(ByVal NewText As String) Private x As DelUpdateTextCallBack = AddressOf UpdateText Private Sub UpdateText(ByVal NewText As String) Me.Text = NewText Application.DoEvents() End Sub then in the mRAS_StateChanged above... If Me.InvokeRequired Then Me.Invoke(x, New Object() {CurrentState}) End If i imagine it's not right, as i'm experiencing the same problems already on the Me.Invoke line, but that was the best i could come up with... Show quoteHide quote > > More then likely you are right - it is occuring on a separate thread. > You should check the Me.InvokeRequired propertie in the callback - if > it is true, then you need to call Me.Invoke so that the call is > marshaled to the UI thread... > > -- > Tom Shelton [MVP] bhc wrote:
Show quoteHide quote > that's what i was afraid of...perhaps you could expand a little bit on bhc - did you ever get this sorted out? I've been sort of out for the> Invoking, as it's definitely not me strong suit... > > what i gather, is that i need to have a Sub that updates the form text, > declare a Delegate that has the same signature, and a variable of the > Delegate type that has an AddressOf pointing to the Sub. what i have > right now.... > > Private Delegate Sub DelUpdateTextCallBack(ByVal NewText As String) > Private x As DelUpdateTextCallBack = AddressOf UpdateText > > Private Sub UpdateText(ByVal NewText As String) > Me.Text = NewText > Application.DoEvents() > End Sub > > then in the mRAS_StateChanged above... > > If Me.InvokeRequired Then > Me.Invoke(x, New Object() {CurrentState}) > End If > > i imagine it's not right, as i'm experiencing the same problems already > on the Me.Invoke line, but that was the best i could come up with... last couple of days... I got your email, and I came back here to check if any other answers were offered - apparently not. I can try and do a little bit of playing with this at home tonight, if you still need the help.... -- Tom Shelton [MVP] hi tom - thanks for getting back to me.
turns out this was my fault - although it still doesn't make much sense to me. here's the deal...in the calling thread, i started dialing, then entered a loop where i slept 100 miliseconds at a time. when the event came bubbling up from the RasCallBack, any screen update would cause the program to freeze. well...all i have to do was throw in a DoEvents, and it worked. i imagine the screen wasn't able to update for whatever reason, and the DoEvents was needed to flush out the request. just a guess - like i said, i really don't understand why it didn't work to begin with...
Scanning Option Group (VB 6 Option Button Control Array)
Auto-Updates using MSI ExitWindowsEx function not working. String, not Boolean Control.BackColor Transparency, Control.BackColor = Color.Transparent Passing an array of to a Sub Application unhandled exception event question minimize button click event? Treading for console applications in VB.NET Best book/article/tutorial on Exception Handling in multi tier Windows App |
|||||||||||||||||||||||