Jesse Jämsen Jesse Jämsen - 1 month ago 20
C# Question

C# timeout exception not caught

I'm reading some data over TCP/IP and for some reason timeout exception is not caught. Any ideas what's wrong here?

try
{
Timer timer1 = new Timer(dcaika);
timer1.Elapsed += async (sender, e) => await HandleTimer();
timer1.Start();
memoryRes = dc.readBytes(libnodave.daveFlags, 0, 180, 1, memoryBuffer);
timer1.Stop();
}
catch (TimeoutException)
{
}


and here is timeout handling

private static Task HandleTimer()
{
Console.WriteLine("timeout");
throw new TimeoutException();
}

Answer

That's just not the way .NET events work. They don't interrupt a thread; they'll be run in a context determined by the type of timer it is. In this case (System.Timers.Timer), the Timer.Elapsed event handler will be invoked on a thread pool thread. So, it's running on a completely different thread than the try/catch, and that's why it won't work.

It looks like you're trying to force a timeout on an API that doesn't natively support timeouts. There's no clean way to do this. So, the first thing to do is to ask whoever maintains readBytes for timeout support.

There is a way to do "fake timeouts" like this:

var timeoutTask = Task.Delay(dcaika);
var readTask = Task.Run(() => dc.readBytes(libnodave.daveFlags, 0, 180, 1, memoryBuffer));
var completedTask = await Task.WhenAny(timeoutTask, readTask);
if (completedTask == timeoutTask)
  ...
else
  ...

But this approach will not stop the readBytes call, so it will probably continue reading bytes and mess up your other communications. So I don't think it will work for your scenario.