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))(
        Dim t = reader.ReadLineAsync()
        If (Not t.Wait(2000)) Then Throw New MyTimeoutExeption()
        Return t
    End Function).Invoke()

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


Dim nextCommand = Await TryAwait(reader.ReadLineAsync(), 2000)
  • \$\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 '15 at 14:11
  • \$\begingroup\$ @roryap Yeah. And also to make sure exceptions from target are propagated. \$\endgroup\$ – svick Jan 28 '15 at 14:21
  • \$\begingroup\$ What about Timeout? \$\endgroup\$ – John Demetriou Jun 4 '18 at 6:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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