# VBForums CodeBank > CodeBank - Visual Basic .NET >  VB.Net tips and tricks you might be interested in.

## Niya

I just wanted to share some small tips and tricks I've personally been using as of late in VB.Net that makes life just a little bit easier for certain things. These are not big or revolutionary in any way. Just some very minor things that I arrived at as a natural progression of continual use of VB.Net.

*Make any function asynchronous.*


```
Public Class Form1

    Private Function TakeLongTimeToDoSomething(ByVal x As Integer) As Double

        Dim d As Double = CInt(x)

        For i = 1 To 10
            d = d / 9
            Threading.Thread.Sleep(500)
        Next

        Return d
    End Function

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Me.Text = TakeLongTimeToDoSomething(5000)
    End Sub
End Class
```

Look at the above code. You press a button and it executes some long running task after which it returns a value. The problem with the above is that it locks up the UI while it's performing the task. Now your first instinct might be to use multi-threading. You might do something like this:-


```
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Threading.ThreadPool.QueueUserWorkItem(Sub()
                                                   Dim value = TakeLongTimeToDoSomething(5000)

                                                   Me.BeginInvoke(Sub()
                                                                      Me.Text = value.ToString
                                                                  End Sub)

                                               End Sub)


    End Sub
```

Now the above works but it's a little wordy, don't you think? You also have an additional problem in that the button could now be pressed multiple times before the first one completes. You might think to yourself that you could disable the button during the time the work is being done:-


```
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Button1.Enabled = False

        Threading.ThreadPool.QueueUserWorkItem(Sub()
                                                   Dim value = TakeLongTimeToDoSomething(5000)

                                                   Me.BeginInvoke(Sub()
                                                                      Me.Text = value.ToString
                                                                      Button1.Enabled = True
                                                                  End Sub)

                                               End Sub)


    End Sub
```

This works but look at the structure. That is ugly. Firstly it's a lot of boilerplate and now with the disabling and enabling of the buttons you have related things spread between the event handler and the worker thread. That is very difficult to follow and if it gets more complicated, it would become error prone.

So how can we simplify all this? Well you could use a combination of Tasks and Async/Await. All of that could be simplified to this:-


```
    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Button1.Enabled = False

        Me.Text = Await Task.Run(Function() TakeLongTimeToDoSomething(5000).ToString)

        Button1.Enabled = True

    End Sub
```

Doesn't that look a lot more manageable and easy to understand?

*Perform complex initialization of variables*

We are all familiar with variable initialization:-


```
Public Class Form2
    Private _fib = {0, 1, 1, 2, 3, 5, 8, 13}
End Class
```

The above code initializes an array variable with the Fibonacci sequence. Simple right? But what if we wanted to initialize it with a calculation instead. We could do this:-


```
Public Class Form2
    Private _fib As Integer()

    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim a = 0I, b = 1I, c = 0I
        Dim l As New List(Of Integer)
        l.AddRange({a, b})

        For i = 2 To 7
            c = a + b
            l.Add(c)

            a = b
            b = c
        Next

        _fib = l.ToArray

    End Sub
End Class
```

Perfectly reasonable. But now we have separated the initialization from the declaration. What if you started adding more functions to that class and pushed Form2_Load to somewhere in the middle or bottom? Every time you wanted to know how that array was initialized you'd have to wade through a bunch of code to find Form2_Load and to make matters worse, what if you decided to put all initialization into a function that is called by the Load event? That is another level of indirection you'd have to trace. Wouldn't it be nice if we could perform this initialization where it was declared to keep everything more organized? Well you can do this by clever use of an anonymous function. You could do this:-


```
Public Class Form2
    Private _fib As Integer() = (Function()
                                     Dim a = 0I, b = 1I, c = 0I
                                     Dim l As New List(Of Integer)
                                     l.AddRange({a, b})

                                     For i = 2 To 7
                                         c = a + b
                                         l.Add(c)

                                         a = b
                                         b = c
                                     Next

                                     Return l.ToArray
                                 End Function).Invoke()
End Class
```

Now the initialization and the declaration of the array are one unit. This one looks a bit ugly due to how much code there is to calculate a Fibonacci sequence but in practice it won't always be this verbose. You'd mostly use it to set properties on classes where the class constructor doesn't provide adequate means to do so. Here's an actual example from a working program:-


```
    Private client As HttpClient = (Function()
                                        Dim c As New HttpClient

                                        c.DefaultRequestHeaders.UserAgent.Add(New Headers.ProductInfoHeaderValue("NiyaScaper", "1.0"))

                                        Return c
                                    End Function).Invoke
```

*Tracking progress of a function*

This one is my favorite. Let's say you have a function like a file download where you need to track the progress. Look at this:-


```
Public Class Form3
    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Button1.Enabled = False

        Await Task.Run(Sub() DownloadFile())

        MessageBox.Show("Download complete!")

        Button1.Enabled = True
    End Sub

    Private Sub DownloadFile()
        Dim r As New Random

        For i = 1 To 100
            Threading.Thread.Sleep(r.Next(100, 300))
        Next

    End Sub

End Class
```

The above is a mock-up of a downloader. You click the Button and it starts an asynchronous download. When the download is finished, we are informed through a message box. But what if we wanted to track the progress of the download? We might do this:-


```
    Private Sub DownloadFile()
        Dim r As New Random

        For i = 1 To 100

            Me.Invoke(Sub()
                          ProgressBar1.Value = i
                      End Sub)

            Threading.Thread.Sleep(r.Next(100, 300))
        Next

    End Sub
```

We changed our DownloadFile function to report progress to a ProgressBar. This is actually very bad because we have now married our download function to the UI itself. If we wanted to take that function and dump it into it's own class or use it in another project, we must now untangle it from the UI. Good news is, we can unmarry this function from the UI through the use of delegates:-


```
Public Class Form3
    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Button1.Enabled = False

        Await Task.Run(Sub() DownloadFile(Sub(i As Integer)
                                              Me.Invoke(Sub()
                                                            Me.ProgressBar1.Value = i
                                                        End Sub)
                                          End Sub))

        MessageBox.Show("Download complete!")

        Button1.Enabled = True
    End Sub

    Private Sub DownloadFile(Optional ByVal reportProgress As Action(Of Integer) = Nothing)
        Dim r As New Random

        For i = 1 To 100
            If reportProgress IsNot Nothing Then reportProgress.Invoke(i)

            Threading.Thread.Sleep(r.Next(100, 300))
        Next

    End Sub

End Class
```

Now DownloadFile is capable of reporting progress without being married to the UI. You can now freely move that function to wherever you like. The UI code will take responsibility for updating the progress bar as it should. DownloadFile should not even know that a UI exists.

Anyways, that's all I have for today. Have a good day everyone.

----------

