3
\$\begingroup\$

I want to wait for a line to be read, but only for so long before timing out. This is what I came up with. Is there a better way to do it?

Dim reader As New System.IO.StreamReader(pipe)

Dim nextCommand = Await New Func(Of Task(Of String))(
    Function()
        Dim t = reader.ReadLineAsync()
        If (Not t.Wait(2000)) Then Throw New MyTimeoutExeption()
        Return t
    End Function).Invoke()
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

For operations that don't support cancellation themselves, You can combine Task.WhenAny() with Task.Delay():

Async Function TryAwait(Of T)(target As Task(Of T), delay as Integer) As Task(Of T)
    Dim completed = Await Task.WhenAny(target, Task.Delay(delay))
    If completed Is target Then
        Return Await target
    End If

    Throw New TimeoutException()
End Function

Usage:

Dim nextCommand = Await TryAwait(reader.ReadLineAsync(), 2000)
\$\endgroup\$
3
  • \$\begingroup\$ Can you please clarify one thing? Return Await target won't actually continue to await, since it's already completed, right? Is its purpose there only to make sure a Task(Of T) is returned? \$\endgroup\$
    – rory.ap
    Jan 28, 2015 at 14:11
  • \$\begingroup\$ @roryap Yeah. And also to make sure exceptions from target are propagated. \$\endgroup\$
    – svick
    Jan 28, 2015 at 14:21
  • \$\begingroup\$ What about Timeout? \$\endgroup\$ Jun 4, 2018 at 6:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.