Is this a UI-threading issue? Is there an easy way to fix it? - vb.net

I am communicating with a USB-HID device. It will successfully complete hundreds of send-receive requests but occasionally get a Null Exception error.
Is this a threading issue?
FormMain.vb:
myHidDevice.transmitPacket(Packet)
myHidDevice.resetEvent.WaitOne(6)
If myHidDevice.rxDataReady = True then
' Life is good
MyHidDevicePort.vb
Public Sub DataReceivedHandler(ByVal sender as Object, dataReceived as DataReceivedEventArgs)
if dataReceived.data Is Nothing Then
Exit Sub
Else
Dim rDataPacket As List(Of Byte) = dataReceived.data.ToList()
For Each element in rDataPacket
rxData.dataPacket(i) = element
rxDataReady = True
resetEvent.Set()
MySensorClass.vb
Public Overrides Function processPacket(ByRef rxStruct as rStruct, ByVal txPacket()) as Boolean
....
Select Case rxStruct.dataPacket(4)
Case MOD_DISPLAY_SET_BRIGHTNESS
rxData(0) = rxStruct.dataPacket(5)
...
at the rxData.dataPacket(i) = element I will get a NullReference error every now and then. I could enclose it in a try/catch statement, but I'd like to fix the root problem if possible.
This device is communicating to microcontrollers, and it is possible that they won't always give a value... but my feeling is this is some sort of UI threading issue. When debugging, even though there is a null exception, many times there actually does seem to be data in dataReceived.data.ToList(). Is there an easy way to place the whole data processing routine on a thread separate from the UI?
Edit: Changed code to match answer and give more info on where it is used. Still get NullReferenceExceptions after about 1,000 completed send/receive requests to the HID device.

The dialog in the comments is too restricting, so I'll try this as an answer. Unfortunately, there still isn't enough code to give a full answer.
Some sample unknowns:
What is rxData (a custome class, part of the SDK, a struct)?
Where does i come from in the code sample rxData.dataPacket(i) = element, I don't see it decalred or incremented.
Why is the form waiting on myHidDevice.resetEvent.WaitOne(6) and what does it do once it thinks there is sucess?
How/when does processPacket get called?
What I can recommend in general is that access to shared state be wrapped in a SyncLock. And in your case, that includes both rxData and rxDataReady.
In your threaded event callback you need this:
SyncLock(syncRoot)
For Each element in rDataPacket
rxData.dataPacket(i) = element
next
rxDataReady = True
resetEvent.Set()
End SyncLock
And in your Main form where you are waiting for a response you need to wrap access to the ready flag as well:
SyncLock(myHidDevice.syncRoot)
If myHidDevice.rxDataReady = True then
' do something that consumes the data read in the thread
End If
End SyncLock
You have to watch for how long you hold the lock in the read and the write because you cannot be doing both at the same time.
Over all, I wouldn't be surprised if your code code be refactored a bit to make the thread issues easier to deal with. A blocking queue / colletion as you suggested might be a good idea. Just not enough is known of you design/code to give any more concrete advice.

If you know that there is a possibility that your object may be null, placing it inside of a try-catch block would be the incorrect way of handling this situation, as that would be considered coding by exception. Instead, do a null check on your object prior to setting it. e.g.
If Not dataReceived.data Is Nothing Then
Dim rDataPacket As List(Of Byte) = dataReceived.data.ToList()
End If
If your problem lyes with the individual array elements being null, you should also check them to ensure they exist before setting/accessing them.

Related

Using Invoke Method in an IF statement vb.net

I am using a TCP client/server to receive information from a micro controller and using that information inside a Win Forms App, VB.NET. My issue is trying to check a label against a datatable in an IF statement. I have tried different forms of invoke but none of them seem to work.
VB Code
If lblStep.Invoke(New MethodInvoker(Sub() lblStep.Text = lblStep.Text), Nothing) = dt.Rows(0).Item("Step") Then
'Do something
end if
The error I am receiving is a multi thread error.
If you expect to get a value returned then you need to invoke a method that returns a value, which means a function. You could do this:
If CStr(lblStep.Invoke(Function() lblStep.Text)) = dt.Rows(0).Field(Of String)("Step") Then
or this:
If CBool(lblStep.Invoke(Function() lblStep.Text = dt.Rows(0).Field(Of String)("Step"))) Then
The first one gets the String from the UI thread and performs the comparison on the background thread while the second performs the comparison on the UI thread.
Note that I also make sure that everything is the correct data type, which is required if you have set Option Strict On, which you absolutely should have done.

With... End With vs Using in VB.NET

I just found out that like C#, VB.NET also has the using keyword.
Until now I thought it didn't have it (stupid of me, I know...) and did stuff like this instead:
With New OleDbConnection(MyConnectionString)
' Do stuff
End With
What are the implications of this compared to doing it with a using statement like this
Using cn as New OleDBConnection(MyConnectionString)
With cn
' Do stuff with cn
End With
End using
UPDATE:
I should add that I am familiar with what the using statement does in that it disposes of the object when the construct is exited.
However, as far as I understand the With New ... construct will have the object mark the object as ready for garbage collection when it goes out of scope.
So my question really is, is the only difference the fact that with using I will release the memory right away, whereas with the With construct it will be released whenever the GC feels like it? Or am I missing something bigger here?
Are there any best practice implications? Should I go and rewrite all the code with I used With New MyDisposableObject() ... End With as Using o as New MyDisposableObject()?
With Statements/Blocks
However, as far as I understand the With New ... construct will have the object mark the object as ready for garbage collection when it goes out of scope.
This is both true and not true. It is true in the sense that all objects are "marked" (purists might quibble with this terminology, but the details are not relevant) as ready for garbage collection when they go out of scope. But then in that sense, it is also not entirely true, as there's nothing special about the With keyword with respect to this behavior. When an object goes out of scope, it is eligible for garbage collection. Period. That's true for method-level scope and it's true for block-level scope (e.g., With, For, Using, etc.).
But that's not why you use With. The reason is that it allows you to set multiple properties in sequence on a deeply-nested object. In other words, assume you have an object on which you want to set a bunch of properties, and you access it this way: MyClass.MemberClass.AnotherMemberClass.Items(0). See all those dots? It can (theoretically) become inefficient to write code that has to work through that series of dots over and over to access the exact same object each time you set a property on it. If you know anything about C or C++ (or any other language that has pointers), you can think of each of those dots as implying a pointer dereference. The With statement basically goes through all of that indirection only once, storing the resulting object in a temporary variable, and allowing you to set properties directly on that object stored in the temporary variable.
Perhaps some code would help make things clearer. Whenever you see a dot, think might be slow!
Assume that you start out with the following code, retrieving object 1 from a deeply-nested Items collection and setting multiple properties on it. See how many times we have to retrieve the object, even though it's exactly the same object every time?
MyClass.MemberClass.AnotherMemberClass.Items(0).Color = Blue
MyClass.MemberClass.AnotherMemberClass.Items(0).Width = 10
MyClass.MemberClass.AnotherMemberClass.Items(0).Height = 5
MyClass.MemberClass.AnotherMemberClass.Items(0).Shape = Circle
MyClass.MemberClass.AnotherMemberClass.Items(0).Texture = Shiny
MyClass.MemberClass.AnotherMemberClass.Items(0).Volume = Loud
Now we modify that code to use a With block:
With MyClass.MemberClass.AnotherMemberClass.Items(0)
.Color = Blue
.Width = 10
.Height = 5
.Shape = Circle
.Texture = Shiny
.Volume = Loud
End With
The effect here, however, is identical to the following code:
Dim tempObj As MyObject = MyClass.MemberClass.AnotherMemberClass.Items(0)
tempObj.Color = Blue
tempObj.Width = 10
tempObj.Height = 5
tempObj.Shape = Circle
tempObj.Texture = Shiny
tempObj.Volume = Loud
Granted, you don't introduce a new scope, so tempObj won't go out of scope (and therefore be eligible for garbage collection) until the higher level scope ends, but that's hardly ever a relevant concern. The performance gain (if any) attaches to both of the latter two code snippets.
The real win of using With blocks nowadays is not performance, but readability. For more thoughts on With, possible performance improvements, stylistic suggestions, and so on, see the answers to this question.
With New?
Adding the New keyword to a With statement has exactly the same effect that we just discussed (creating a local temporary variable to hold the object), except that it's almost an entirely pointless one. If you need to create an object with New, you might as well declare a variable to hold it. You're probably going to need to do something with that object later, like pass it to another method, and you can't do that in a With block.
It seems that the only purpose of With New is that it allows you to avoid an explicit variable declaration, instead causing the compiler to do it implicitly. Call me crazy, but I see no advantage in this.
In fact, I can say that I have honestly never seen any actual code that uses this syntax. The only thing I can find on Google is nonsense like this (and Call is a much better alternative there anyway).
Using Statements/Blocks
Unlike With, Using is incredibly useful and should appear frequently in typical VB.NET code. However, it is very limited in its applicability: it works only with objects whose type implements the IDisposable interface pattern. You can tell this by checking to see whether the object has a Dispose method that you're supposed to call whenever you're finished with it in order to release any unmanaged resources.
That is, by the way, a rule you should always follow when an object has a Dispose method: you should always call it whenever you're finished using the object. If you don't, it's not necessarily the end of the world—the garbage collector might save your bacon—but it's part of the documented contract and always good practice on your part to call Dispose for each object that provides it.
If you try to wrap the creation of an object that doesn't implement IDisposable in a Using block, the compiler will bark at you and generate an error. It doesn't make sense for any other types because its function is essentially equivalent to a Try/Finally block:
Try
' [1: Create/acquire the object]
Dim g As Graphics = myForm.CreateGraphics()
' [2: Use the object]
g.DrawLine(Pens.Blue, 10, 10, 100, 100)
' ... etc.
End Try
Finally
' [3: Ensure that the object gets disposed, no matter what!]
g.Dispose()
End Finally
But that's ugly and becomes rather unwieldy when you start nesting (like if we'd created a Pen object that needed to be disposed as well). Instead, we use Using, which has the same effect:
' [1: Create/acquire the object]
Using g As Graphics = myForm.CreateGraphics()
' [2: Use the object]
g.DrawLine(Pens.Blue, 10, 10, 100, 100)
' ...etc.
End Using ' [3: Ensure that the object gets disposed, no matter what!]
The Using statement works both with objects you are first acquiring (using the New keyword or by calling a method like CreateGraphics), and with objects that you have already created. In both cases, it ensures that the Dispose method gets called, even if an exception gets thrown somewhere inside of the block, which ensures that the object's unmanaged resources get correctly disposed.
It scares me a little bit that you have written code in VB.NET without knowing about the Using statement. You don't use it for the creation of all objects, but it is very important when you're dealing with objects that implement IDisposable. You definitely should go back and re-check your code to ensure that you're using it where appropriate!
By using With...End With, you can perform a series of statements on a specified object without specifying the name of the object multiple times.
A Using block behaves like a Try...Finally construction in which the Try block uses the resources and the Finally block disposes of them.
Managed resources are disposed by the garbage collector without any extra coding on your part.
You do not need Using or With statements.
Sometimes your code requires unmanaged resources. You are responsible for their disposal. A Using block guarantees that the Dispose method on the object is called when your code is finished with them.
The difference is the Using With...End End
Using cn as New OleDBConnection(MyConnectionString)
With cn
' Do stuff with cn
End With
End using
Calls cn.Dispose() automatically when going out of scope (End Using). But in the With New...End
With New OleDbConnection(MyConnectionString)
' Do stuff
End With
.Dispose() is not explicitly called.
Also with the named object, you can create watches and ?cn in the immediate window. With the unnamed object, you cannot.
Using connection... End Using : Be careful !!!
This statement will close your database connection !
In the middle of a module or form(s), i.e.adding or updating records, this will close the connection. When you try to do another operation in that module you will receive a database error. For connections, I no longer use it. You can use the Try... End Try wihthouth the Using statement.
I open the connection upon entry to the module and close it it upon exit. That solves the problem.

NSubstitute and mocking an object to fire an event

I'm currently using NSubstitute as my mocking framework and over I'm doing reasonably well, with one exception that is...
I'm attempting to mock an interaction that calls an event from inside my mocked object, unfortunately I'm really struggling to do this. The setup is something like this...
Public Interface IMockObject
Event MyMockedEvent( someId as Integer )
Sub MyRoutineThatInvokesMyMockedEvent( someId as Integer)
End Interface
...so in my Unit Test I need to mock the 'MyRoutineThatInvokesMyMockedEvent' to receive the ID and then raise the 'MyMockedEvent'. So far I have come up with...
Dim mockedObject = Substitute.For(Of IMockObject)()
mockedObject.When(
Sub(x) x.MyRoutineThatInvokesMyMockedEvent( 999 )).Do(
Sub(y) 'RaiseTheEventHere )
...but I'm stuck on actually raising the event with the following not valid...
mockedObject.When(
Sub(x) x.MyRoutineThatInvokesMyMockedEvent( 999 )).Do(
Sub(y) RaiseEvent MyMockedEvent(999) )
...I do have a theory that this may not be possible in VB.NET (without creating a helper routine) but will gladly appreciate any help on how to achieve the above without the helper routine.
OK, found the answer. Or something like it.
The problem I believe is due to the event definition that is used - by reconfiguring the 'MyMockedEvent' to use its own 'MyMockedEventArgs' (inheriting from System.EventArgs) the event can be raised without it complaining about passing through an inappropriate type.
mockedObject.When(
Sub(x) x.MyRoutineThatInvokesMyMockedEvent( 999 )).Do(
Sub(y) RaiseEvent IMockObject.MyMockedEventEventHandler() )
But its here where my suspicions of VB.NET doing some black magic come into play as I'm aware that VB.NET with create the delegates for the event behind the scenes. Of course, the fact that Intellisense doesn't show the EventHandler doesn't particularly help either and I'm guessing I could manually code up the delegate but this approach seems quicker.
HTH

MATLAB - objects not clearing when timers are involved

This is somewhat related to this question, but not quite.
I have two classes, FunctionWrapper and TimerWrapper:
classdef FunctionWrapper < handle
methods
function Fcn(obj)
disp('FunctionWrapper.Fcn was called!');
end
end
end
classdef TimerWrapper < handle
properties
Timer
end
methods
function obj = TimerWrapper(other_object)
obj.Timer = timer;
set(obj.Timer, 'Period', 1);
set(obj.Timer, 'ExecutionMode', 'fixedSpacing');
set(obj.Timer, 'TimerFcn', #(event, data) other_object.Fcn);
end
function start(obj)
start(obj.Timer);
end
function stop(obj)
stop(obj.Timer);
end
function delete(obj)
disp('destructor called!');
delete(obj.Timer);
end
end
end
Say I execute the following code in the Command Window:
>> F = FunctionWrapper;
>> T = TimerWrapper(F);
>> clear T %# T's destructor not called
>> timerfind %# just to verify that no, the destructor was never called
Timer Object: timer-1
Timer Settings
ExecutionMode: fixedSpacing
Period: 1
BusyMode: drop
Running: off
Callbacks
TimerFcn: #(event,data)other_object.Fcn
ErrorFcn: ''
StartFcn: ''
StopFcn: ''
What's going on here? I know that timer objects need to be manually deleted, but I thought that would be dealt with in the destructor for TimerWrapper. Without using Amro's ugly but straightforward workaround to overload the clear command, is there a way to clear T from the workspace? Furthermore, nothing is referring to T, so why does a reference to it exist? (The fact that the destructor is never called implies this fact.) Is this buried in the timer object itself?
If you type t = TimerWrapper; f = functions(t.Timer.TimerFcn); f.workspace(2), you'll see that the workspace of the anonymous function used for the callback contains a reference to the TimerWrapper object itself. So there's a kind of circular reference there which is not picked up by clear.
Given how you've set things up, you can remove T (and its underlying timer object) by calling the destructor explicitly and then calling clear.
T.delete
clear T
The difference between clear and delete is kind of confusing (to me, anyway). As you've found, clear doesn't explicitly call the destructor. It just removes the name T from the workspace. So T, and its underlying timer, still exist at that point. If they contained no references to things that still existed, MATLAB would then remove T properly, including calling its destructor. As it is, since the timer contains a reference (in its callback) to T, which still exists, the timer (and thus T as well) is not deleted.
You can find it (despite not having a name in the workspace) with timerfindall, and if you explicitly delete it yourself using
tmrs = timerfindall;
delete(tmrs);
you'll find that T is now properly gone.
I'm not so sure that this is a bug, although I find it pretty confusing, and the distinction between clear and delete could probably be documented better.
As to a workaround, I don't find it a big pain to explicitly call delete, although it's a bit more of a pain to clean things up if you accidentally call clear. I would think the suggestion in message #5 from the thread you linked to, rather than message #4, would be more general and robust.
I don't think you should overload clear in the way #Amro suggests in the separate thread you linked to: although this may work if you call clear T explicitly, you may still get into trouble if you call clear all, or clear variables. (I haven't tried it just now, but I believe these syntaxes of clear don't even loop over things in the workspace and call clear on each - instead they call the clear method of the internal MATLAB workspace object, and that's going to get confusing fast).
It seems as though this might be because the timer's callback is set to a non-default value. A proposed workaround (see message#4 of the linked thread) is to set the callback function only when the start method is called, then setting it to null when the stop method is called.

Will statements or expressions execute after a return statement in VB.net?

Ok, I was rooting around in one of our company apps which is done in VB.net. I'm not familiar with VB.net (I do stuff in C#) so I'm asking this question: Does the code after the clean up comment execute?
Public Function DoesUserHavePermission(ByVal UserID As Integer, ByVal ActionID As Integer) As Boolean
' some extra code re: getting data
Return UserHasPermission
'-Clean Up-
MySqlCommand.Dispose()
MySqlConnection.Dispose()
RowCount = Nothing
End Function
It is my understanding once you say return, you give the calling function control again. Is this a VB.Net oddity which I have to accept or a giant WTF?
The statements after the Clean up comment will not execute. This is a candidate for enclosure within Try/Catch/Finally.
Not unless there's some control logic you omitted in your example
The code should be (the clean up that is) wrapped inside of a finally statement by using a try catch exception:
pseudo:
try
'make conn
catch exception
finally
mysqlCmd.Dispose
....
end try
Is it possible it will still run..possibly...I used to write VB.net and it has been quite some time but I do remember oddities like that. I can't give you a sure answer as this is / was very bad practice. What you can do is clean it up and set some break points in y our code and debug. See if the code comes back to it...
Short answer: The code below the return will never execute.
That looks like translated code. Like someone took a C# snippet from the web and tried to write it in VB for VS 2003 (before VB supported the USING statement, but while C# did).
where the MySqlConnection and MySqlCommand are new'd up should be put in USING blocks and the Dispose() lines turned into END USING.
Where possible, use USING over TRY/FINALLY to ensure cleanup of IDisposable objects.
using mySqlConnection as New SqlConnection(connectionString)
mySqlConnection.Open
using mySqlCommand as New SqlCommand(commandString, mySqlConnection)
'do something that may fail'
return UserHasPermission
end using 'disposes mySqlCommand'
end using 'closes/disposes mySqlConnection'
You can use this pattern for SqlTransactions too. (Place after mySqlConnection.Open)
using myTerribleVariableName as SqlTransaction = mySqlConnection.BeginTransaction
'do something that may fail - multiple SqlCommands maybe'
'be sure to reference the transaction context in the SqlCommand'
myTerribleVariableName.Commit
end using 'disposes. rollsback if not commited'
Oh, and you can delete the RowCount = Nothing statement.
That to me is a giant WTF and a very difficult thing to miss, normally peer code review can catch that, I do not understand why a return from the function is placed earlier on prior to the cleanup. That could have been done during the testing of the code where the programmer was wanting to test the function first and decided to ignore the cleanup code by returning from it quickly enough, I suspect the cleanup code could be lengthy, ie. maybe it is throwing an exception that is not properly caught and wanted to ignore it hence a need to return immediately...That is an (un) intentional side effect of introducing a leak as the resource is not cleaned up properly thereby masking the real problem...that's my take on it.
Hope this helps,
Best regards,
Tom.
The code as presented will not do anything after the return statement. VB.NET and C# are similar in that fashion.
Its possible that this code was written by a VB6 programmer, trusting in old paradigms, or possibly this was the work of the upgrade tool, porting code from VB6 to VB.NET.