VB.Net how to run a function in a seperate thread

Hi Experts
I have two simple functions - one checks the status of a server and returns true or false, the other sends an email based
on data passed to it.    I need to free up the GUI while these functions operate and would like to operate them on separate threads so that the continuous progressbar runs and the users can continue.
Please could someone give me an example of how to run a function like that on a separate thread, how to pass data to it and receive a result from it.  I've seen many examples on the web of the backgroundworker, but none that operate it as a function. Many thanks
LVL 2
PNRTAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CodeCruiserCommented:
Example code for starting thread here

https://support.microsoft.com/en-us/kb/315577


Private Sub Form1_Load( _
    ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles MyBase.Load

    Private trd As Thread
    trd = New Thread(AddressOf ThreadTask)
    trd.IsBackground = True
    trd.Start()
End Sub


Private Sub ThreadTask()
    Dim stp As Integer
    Dim newval As Integer
    Dim rnd As New Random()

    Do
        stp = ProgressBar1.Step * rnd.Next(-1, 2)
        newval = ProgressBar1.Value + stp
        If newval > ProgressBar1.Maximum Then
            newval = ProgressBar1.Maximum
        ElseIf newval < ProgressBar1.Minimum Then
            newval = ProgressBar1.Minimum
        End If

        ProgressBar1.Value = newval

        Thread.Sleep(100)
    Loop
End Sub

Open in new window



Also

https://msdn.microsoft.com/en-us/library/ts553s52(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1
0
PNRTAuthor Commented:
Thanks, I've seen this many times, but as per my question, I was looking for how to operate a function, sending data to it and receiving a result from it
0
R555BCommented:
So do you want to check the server status then send an email based on it?

How does the data get passed to the second function ?
0
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

CodeCruiserCommented:
Have you seen section "Retrieving data with callback methods" in 2nd link?
0
PNRTAuthor Commented:
Hi R555B, thanks for the reply, they are just two simple functions the first gets sent the IP of the server to ping and returns true or false.  The second function gets sent, server, port, user/password and email address and sends and email.
Returning true or false if successful.  Both work fine but I was just trying to get the same functionality without freezing the GUI

Hi CodeCruiser.  thanks for the reply.   LOL, if I wasn't confused before, then reading about callback methods really did it.  Sorry.
0
R555BCommented:
OK, if I was doing that, I'd do something like this....


dim b as new backgroundworker
addhandler b.dowork, addressof Testsub
dim parameters as string = IP & "//" & server & "//" & port
b.runworkerasync(parameters)


public sub testsub(byval sender as object, byval e as doworkeventargs)
dim sub_params() as string = e.argument.tostring.split("//")
dim IP as string = spilts(0)

ping_function(ip)
mail_function(other parameters...)

end sub

Open in new window



Or something along those lines. Pass all the parameters to a background worker as one big string. Parse them into separate variables and the pass those to the functions.
If youve got multiple servers, ports etc youll want to loop it somehow as well.
0
Fernando SotoRetiredCommented:
Hi PNRT;

Add a BackgroundWorker component to your form and code like below will show how it can be done.

Imports System.ComponentModel

Public Class Form1

    Public Sub New()
        InitializeComponent()
        backgroundWorker1.WorkerReportsProgress = True
        backgroundWorker1.WorkerSupportsCancellation = True
    End Sub

    Private Function GetServerStatus(ByVal server As String) As Boolean
        Return True '' Change this function to return the server status 
    End Function

    '' Use as many parameters as needed
    Private Sub SendEmail(ByVal emailAddress As String)
        Debug.Print("Email Sent to : " & emailAddress)
    End Sub

    Private Sub startAsyncButton_Click(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles startAsyncButton.Click
        If BackgroundWorker1.IsBusy <> True Then
            ' Start the asynchronous operation passing in a server to check
            BackgroundWorker1.RunWorkerAsync({"Server1", "Tom@EE.com"})
        End If
    End Sub

    Private Sub cancelAsyncButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cancelAsyncButton.Click
        If backgroundWorker1.WorkerSupportsCancellation = True Then
            ' Cancel the asynchronous operation.
            backgroundWorker1.CancelAsync()
        End If
    End Sub

    ' This event handler is where the time-consuming work is done. 
    Private Sub backgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        worker.ReportProgress(0)
        Dim serverToCheck As String = e.Argument(0).ToString()
        Dim email As String = e.Argument(1).ToString()
        Dim serverStatus As Boolean = GetServerStatus(serverToCheck)
        worker.ReportProgress(50)
        SendEmail(email)
        worker.ReportProgress(100)
    End Sub

    ' This event handler updates the progress. 
    Private Sub backgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        resultLabel.Text = resultLabel.Text & vbCrLf & (e.ProgressPercentage.ToString() + "% completed")
    End Sub

    ' This event handler deals with the results of the background operation. 
    Private Sub backgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        resultLabel.Text = resultLabel.Text & vbCrLf
        If e.Cancelled = True Then
            resultLabel.Text = resultLabel.Text & "Canceled!"
        ElseIf e.Error IsNot Nothing Then
            resultLabel.Text = resultLabel.Text & "Error: " & e.Error.Message
        Else
            resultLabel.Text = resultLabel.Text & "Done!"
        End If
    End Sub

End Class

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
R555BCommented:
or alternativley...

dim b as new backgroundworker
addhandler b.dowork, addressof ping_function
b.runworkerasync(Ip_address)

Open in new window


That may not work as well though as I think the backgroundworker stil expects things to be passed to it as e.Arguments as opposed to a regular parameter.
You may find that way the ping_function returns an exception as its got nothing to ping
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.