in sources/Google.Solutions.IapDesktop.Extensions.Management/ToolWindows/SerialOutput/SerialOutputModel.cs [93:158]
public Task TailAsync(Action<string> newOutputFunc, CancellationToken token)
{
return Task.Run(async () =>
{
ApplicationTraceSource.Log.TraceVerbose("Start polling serial output");
var exceptionCaught = false;
while (!exceptionCaught)
{
//
// Check if we can continue to tail.
//
if (token.IsCancellationRequested)
{
ApplicationTraceSource.Log.TraceVerbose("Stop polling serial output");
break;
}
string? newOutput;
try
{
ApplicationTraceSource.Log.TraceVerbose("Polling serial output...");
newOutput = await ReadAndBufferAsync(token).ConfigureAwait(false);
}
catch (TokenResponseException e)
{
newOutput = "Reading from serial port failed - session timed out " +
$"({e.Error.ErrorDescription})";
exceptionCaught = true;
}
catch (Exception e) when (e.IsCancellation())
{
//
// This is deliberate, so do not emit anything to output.
//
newOutput = null;
}
catch (Exception e)
{
newOutput = $"Reading from serial port failed: {e.Unwrap().Message}";
exceptionCaught = true;
}
//
// By the time we read the data, the form might have begun closing. In this
// case, updating the UI would cause an exception.
//
if (!token.IsCancellationRequested && newOutput != null && !string.IsNullOrEmpty(newOutput))
{
newOutputFunc(newOutput);
}
try
{
await Task.Delay(TimeSpan.FromSeconds(1), token).ConfigureAwait(false);
}
catch (TaskCanceledException)
{
//
// Do not let the exception escape, instead handle the cancellation
// in the next iteration.
//
}
}
});
}