Archive

Archive for the ‘Visual Basic’ Category

LINQ on Form’s Controls

December 10th, 2009 robber.baron No comments

When loading a particular form in a project of mine I needed to shift the location of most of my controls to “hide” an unused textbox based on a boolean. I was going to simply loop through each control and ignore the shift in location if the name values were the two controls that were fixed but I thought about how LINQ to Objects could help. While this is simple and probably overkill the potential is awesome.

1
2
3
4
5
6
Dim res = From ctrl In Controls.OfType(Of Control)() _
             Where ctrl.Name <> "txtAddress" AndAlso ctrl.Name <> "lblAddress"
 
For Each ctrl As Control In res
     ctrl.Top -= val
Next

Admittedly this is pretty boring. But say you wanted to change the background color of all textboxes on a form that contain a string greater than 255 and are not read only.

1
2
3
4
5
6
Dim res = From ctrl In Controls.OfType(Of TextBox)() _
             Where ctrl.Text.Length > 255 And ctrl.ReadOnly = False
 
For Each ctrl As Control In res
     ctrl.BackgroundColor = Colors.Red
Next

Very quickly you can see how LINQ can be a convenient tool for all sorts of problems. And ends up being very, very readable as well.

Memory Stats on Mobile Device

December 10th, 2009 robber.baron No comments

Recently I was working on a mobile project that was experiencing some serious memory leak issues. It turns out that I wasn’t disposing for a SqlCeResultSet properly and on each query (of which there was substantial amount) I was calling New() without Dispose().

After a day of feeling like my project was falling apart before my eyes and getting weird and unreliable results from the .NETCF Remote Profiler I searched far a wide for some way to determine the available memory on a device. On MSDN I found the following code (slightly modified by me) to get relevant information.

Basically two P/Invokes later I had the information I needed, saw that I was in fact leaking memory, quickly determined where, and restored sanity to my project. Within thirty minutes of implementing this class the world was a happier place for me.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Imports System.Text
 
Public Class MEMORYSTATUSINFO
    Public Structure MEMORYSTATUS
        Public dwLength As UInt32
        Public dwMemoryLoad As UInt32
        Public dwTotalPhys As UInt32
        Public dwAvailPhys As UInt32
        Public dwTotalPageFile As UInt32
        Public dwAvailPageFile As UInt32
        Public dwTotalVirtual As UInt32
        Public dwAvailVirtual As UInt32
    End Structure
 
    Public Declare Function GlobalMemoryStatus Lib "CoreDll.Dll" _
    (ByRef ms As MEMORYSTATUS) As Integer
 
    Public Declare Function GetSystemMemoryDivision Lib "CoreDll.Dll" _
        (ByRef lpdwStorePages As UInt32, _
        ByRef ldpwRamPages As UInt32, _
        ByRef ldpwPageSize As UInt32) As Integer
 
    Public Shared Function ShowMemory() As String
        Dim storePages As UInt32
        Dim ramPages As UInt32
        Dim pageSize As UInt32
        Dim res As Integer = _
            GetSystemMemoryDivision(storePages, ramPages, pageSize)
 
        ' Call the native GlobalMemoryStatus method
        ' with the defined structure.
        Dim memStatus As New MEMORYSTATUS
        GlobalMemoryStatus(memStatus)
 
        Dim load As Integer = memStatus.dwMemoryLoad / (1024 * 1024)
        Dim totPhys As Integer = memStatus.dwTotalPhys / (1024 * 1024)
        Dim availPhys As Integer = memStatus.dwAvailPhys / (1024 * 1024)
        Dim totalPageFile As Integer = memStatus.dwTotalPageFile
        Dim availPageFile As Integer = memStatus.dwAvailPageFile
        Dim totVirtual As Integer = memStatus.dwTotalVirtual / (1024 * 1024)
        Dim availVirtual As Integer = memStatus.dwAvailVirtual / (1024 * 1024)
 
        ' Use a StringBuilder for the message string.
        Dim MemoryInfo As New StringBuilder
        MemoryInfo.Append("Memory Load: " _
            & load.ToString() & "Mb" & vbCrLf)
        MemoryInfo.Append("Total Physical: " _
            & totPhys & "Mb" & vbCrLf)
        MemoryInfo.Append("Avail Physical: " _
            & availPhys & "Mb" & vbCrLf)
        MemoryInfo.Append("Total Page File: " _
            & totalPageFile.ToString() & vbCrLf)
        MemoryInfo.Append("Avail Page File: " _
            & availPageFile.ToString() & vbCrLf)
        MemoryInfo.Append("Total Virtual: " _
            & totVirtual.ToString() & "Mb" & vbCrLf)
        MemoryInfo.Append("Avail Virtual: " _
            & availVirtual.ToString() & "Mb" & vbCrLf)
 
        ' Show the available memory.
        Return MemoryInfo.ToString()
    End Function
End Class

Hope this helps someone else find greedy memory hog code in their apps.

Linq on the Compact Framework

December 3rd, 2009 robber.baron No comments

I am a large fan of Linq when coding. I think it is a really clean and concise way to access large sets of data (whether in a database, xml, or a IList) quickly, efficiently, and in a clearly readable way.

I have been developing almost exclusively within the compact framework and while the compact framework (3.5) does not include Linq to Sql it does include Linq to XML and Linq to Objects. The problem I had was getting it to work in the compact framework.

While Imports System.Linq always failed to a lack of reference it was because there is no System.Linq.dll. The linq parts of the language are included within System.Core. Add that reference to your project and Linq will work for you.

Don’t know why it took me so long to realize this. But now I’m Linq free.

I also hear that Compact Framework 4.0 will support Linq to Sql.

Visual Basic Conditionals

October 1st, 2009 robber.baron No comments

At my current job I write far more Visual Basic code than I do C# code. Having started programming in C++ in junior year of high school and using almost exclusively C++ and Java in college, I tend to favor C based languages. One of the more natural things about C(++/#) that I found lacking in Visual Basic was intelligent conditional testing.

For example:

Dim student as Student = Nothing
 
If student IsNot Nothing And student.Name = "robber.baron" Then
     GiveStudentAnA(student)
EndIf
var student as Student = null;
 
if (student != null &amp;&amp; student.Name == "robber.baron")
     GiveStudentAnA(student);

In the C# code when the conditional is a logical And (signified by the double ampersand) and the first condition fails it immediately exits the conditional.  Since both values must be true to continue if the first is false the conditional fails and there is no need to evaluate the second condition.

In the Visual Basic code you will get a “Object Reference not set to Instance of Object” exception because Visual Basic does not implicitly have this feature.  The test for null will fail but the second condition will still be evaluated! I never liked this feature and found it to be a concrete failure in Visual Basic.

Recently I discovered that of course Visual Basic allows you to do this.  (The CLR is the CLR is the CLR.  It is all common under the hood.)  It just needs to you explicitly request this behavior using the AndAlso or OrElse keywords.

Dim student as Student = Nothing
 
If student IsNot Nothing AndAlso student.Name = "robber.baron" Then
     GiveStudentAnA(student)
EndIf

This is how you would properly translate the C# code above into Visual Basic.

If you wanted the inverse, you only wanted the right side condition to evaluate only if the left is true you could do the following:

Dim student as Student = new Student("robber.baron", "C")
 
If student.Name = "robber.baron" OrElse Not student.Grade = "A" Then
     GiveStudentAnA(student)
EndIf

Finally I can combine null checks and logic checks into a single conditional correctly.

Categories: Programming, Visual Basic Tags: