Declares the name, parameters, and code that define a
[ <attributelist> ] [ Partial ] [ accessmodifier ] [ proceduremodifiers ] [ Shared ] [ Shadows ] [ Async ] Sub name [ (Of typeparamlist) ] [ (parameterlist) ] [ Implements implementslist | Handles eventlist ] [ statements ] [ Exit Sub ] [ statements ] End Sub
Optional. See Attribute List.
Optional. Indicates definition of a partial method. See Partial Methods.
Optional. Can be one of the following:
Optional. Can be one of the following:
Optional. See Shared.
Optional. See Shadows.
Optional. See Async.
Required. Name of the procedure. See Declared Element Names. To create a constructor procedure for a class, set the name of a
Subprocedure to the
Newkeyword. For more information, see Object Lifetime: How Objects Are Created and Destroyed.
Optional. List of type parameters for a generic procedure. See Type List.
Optional. List of local variable names representing the parameters of this procedure. See Parameter List.
Optional. Indicates that this procedure implements one or more
Subprocedures, each one defined in an interface implemented by this procedure's containing class or structure. See Implements Statement.
Implementsis supplied. List of
Subprocedures being implemented.
implementedprocedure [ , implementedprocedure ... ]
implementedprocedurehas the following syntax and parts:
Required. Name of an interface implemented by this procedure's containing class or structure.
Required. Name by which the procedure is defined in
Optional. Indicates that this procedure can handle one or more specific events. See Handles.
Handlesis supplied. List of events this procedure handles.
eventspecifier [ , eventspecifier ... ]
eventspecifierhas the following syntax and parts:
Required. Object variable declared with the data type of the class or structure that raises the event.
Required. Name of the event this procedure handles.
Optional. Block of statements to run within this procedure.
Terminates the definition of this procedure.
All executable code must be inside a procedure. Use a
Sub procedure when you don't want to return a value to the calling code. Use a
Function procedure when you want to return a value.
Defining a Sub Procedure
You can define a
Sub procedure only at the module level. The declaration context for a sub procedure must, therefore, be a class, a structure, a module, or an interface and can't be a source file, a namespace, a procedure, or a block. For more information, see Declaration Contexts and Default Access Levels.
Sub procedures default to public access. You can adjust their access levels by using the access modifiers.
If the procedure uses the
Implements keyword, the containing class or structure must have an
Implements statement that immediately follows its
Structure statement. The
Implements statement must include each interface that's specified in
implementslist. However, the name by which an interface defines the
definedname) doesn't have to match the name of this procedure (in
Returning from a Sub Procedure
Sub procedure returns to the calling code, execution continues with the statement after the statement that called it.
The following example shows a return from a
Sub mySub(ByVal q As String) Return End Sub
Exit Sub and
Return statements cause an immediate exit from a
Sub procedure. Any number of
Exit Sub and
Return statements can appear anywhere in the procedure, and you can mix
Exit Sub and
Calling a Sub Procedure
You call a
Sub procedure by using the procedure name in a statement and then following that name with its argument list in parentheses. You can omit the parentheses only if you don't supply any arguments. However, your code is more readable if you always include the parentheses.
Sub procedure and a
Function procedure can have parameters and perform a series of statements. However, a
Function procedure returns a value, and a
Sub procedure doesn't. Therefore, you can't use a
Sub procedure in an expression.
You can use the
Call keyword when you call a
Sub procedure, but that keyword isn't recommended for most uses. For more information, see Call Statement.
Visual Basic sometimes rearranges arithmetic expressions to increase internal efficiency. For that reason, if your argument list includes expressions that call other procedures, you shouldn't assume that those expressions will be called in a particular order.
Async Sub Procedures
By using the Async feature, you can invoke asynchronous functions without using explicit callbacks or manually splitting your code across multiple functions or lambda expressions.
If you mark a procedure with the Async modifier, you can use the Await operator in the procedure. When control reaches an
Await expression in the
Async procedure, control returns to the caller, and progress in the procedure is suspended until the awaited task completes. When the task is complete, execution can resume in the procedure.
Async procedure returns to the caller when either the first awaited object that’s not yet complete is encountered or the end of the
Async procedure is reached, whichever occurs first.
You can also mark a Function Statement with the
Async modifier. An
Async function can have a return type of Task<TResult> or Task. An example later in this topic shows an
Async function that has a return type of Task<TResult>.
Sub procedures are primarily used for event handlers, where a value can't be returned. An
Async``Sub procedure can't be awaited, and the caller of an
Async``Sub procedure can't catch exceptions that the
Sub procedure throws.
Async procedure can't declare any ByRef parameters.
The following example uses the
Sub statement to define the name, parameters, and code that form the body of a
Sub computeArea(ByVal length As Double, ByVal width As Double) ' Declare local variable. Dim area As Double If length = 0 Or width = 0 Then ' If either argument = 0 then exit Sub immediately. Exit Sub End If ' Calculate area of rectangle. area = length * width ' Print area to Immediate window. Debug.WriteLine(area) End Sub
In the following example,
DelayAsync is an an
Async``Function that has a return type of Task<TResult>.
DelayAsync has a
Return statement that returns an integer. Therefore, the function declaration of
DelayAsync must have a return type of
Task(Of Integer). Because the return type is
Task(Of Integer), the evaluation of the
Await expression in
DoSomethingAsync produces an integer, as the following statement shows:
Dim result As Integer = Await delayTask.
startButton_Click procedure is an example of an
Async Sub procedure. Because
DoSomethingAsync is an
Async function, the task for the call to
DoSomethingAsync must be awaited, as the following statement shows:
Await DoSomethingAsync(). The
startButton_Click``Sub procedure must be defined with the
Async modifier because it has an
' Imports System.Diagnostics ' Imports System.Threading.Tasks ' This Click event is marked with the Async modifier. Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click Await DoSomethingAsync() End Sub Private Async Function DoSomethingAsync() As Task Dim delayTask As Task(Of Integer) = DelayAsync() Dim result As Integer = Await delayTask ' The previous two statements may be combined into ' the following statement. ' Dim result As Integer = Await DelayAsync() Debug.WriteLine("Result: " & result) End Function Private Async Function DelayAsync() As Task(Of Integer) Await Task.Delay(100) Return 5 End Function ' Output: ' Result: 5