Home > Software design >  VB.NET - Passing expression to be used within a function
VB.NET - Passing expression to be used within a function

Time:12-04

Part of my program consists of a series of steps that either complete, or time out after a certain interval. Test conditions vary widely. How do I write a single function to encapsulate all possibilities?

To do that I'd ideally need to pass the necessary condition to the function to be evaluated within the function, rather than to be evaluated as a parameter and then passed to the function.

This is what I would ideally want (greatly simplified):

Private Function TestCondition(<CONDITION>) as Boolean 
  ' Returns True if <CONDITION> fulfilled within 10 seconds
  Dim sw as New Diagnostics.StopWatch
  sw.Start()
  While sw.ElapsedMilliseconds < 10000
    If <CONDITION> Return True
    System.Threading.Thread.Sleep(500)
  End While
  sw.Stop()
  Return False
End Function

Function should work with any expression that returns a boolean value:

TestCondition(x=5)
TestCondition(System.IO.File.Exists("myfile")

Obviously, the above doesn't work as the results of specified conditions are passed to the function, rather than the conditions themselves.

Based on other reading, I can likely accomplish this by:

  • Restructuring my code
  • Using delegates
  • Using lambda expressions

but I still do not see exactly how.

Thanks a lot for your help!

CodePudding user response:

You can pass a lambda to the function which can be continually reevaluated.

Private Function TestCondition(predicate As Func(Of Boolean)) As Boolean
    Dim sw As New Diagnostics.Stopwatch()
    sw.Start()
    While sw.ElapsedMilliseconds < 10000
        If predicate() Then Return True
        System.Threading.Thread.Sleep(500)
    End While
    sw.Stop()
    Return False
End Function
Dim result = TestCondition(Function() File.Exists("myfile"))

CodePudding user response:

Basically the same as what djv said,

''' <summary>
''' waits for a condition for a number of seconds
''' </summary>
''' <param name="PredicateFunc">Function() conditional check )</param>
''' <param name="WaitForTMInSecs">seconds to wait</param>
''' <returns>boolean</returns>
''' <remarks></remarks>
Private Function TestCondition(PredicateFunc As Func(Of Boolean),
                                Optional WaitForTMInSecs As Integer = 10) As Boolean
    Dim sw As Diagnostics.Stopwatch = Diagnostics.Stopwatch.StartNew
    Dim _wait As TimeSpan = TimeSpan.FromSeconds(WaitForTMInSecs)
    Dim rv As Boolean = PredicateFunc()
    Do While Not rv AndAlso sw.Elapsed <= _wait
        System.Threading.Thread.Sleep(500)
        rv = PredicateFunc()
    Loop
    Return rv
End Function

Tests,

    Dim result As Boolean
    result = TestCondition(Function() String.Equals("foo", "bar"), 2)
    result = TestCondition(Function() String.Equals("foo", "foo"), 2)
    result = TestCondition(Function() IO.File.Exists("myfile"), 2)
  • Related