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)