-
Notifications
You must be signed in to change notification settings - Fork 164
Addressed extra Read() when task was completed #125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Addressed extra Read() when task was completed #125
Conversation
cts.Cancel(); | ||
try { task.Wait(); } | ||
catch (AggregateException exception) | ||
await task; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the task is cancelled you cannot await it. Consider this example:
using var cts = new CancellationTokenSource();
var token = cts.Token;
cts.Cancel();
var t = Task.FromCanceled(token);
await t.ConfigureAwait(false);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Keboo: Are you suggesting this because I didn't await the cancelTask
?
I do await task intentionally, knowing that if it is cancelled it will throw an exception.
It isn't clear what the Task.FromCanceled(token)
gives me in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because you call cts.Cancel just above this, doesn't that always mean this will throw?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the discussion @Keboo .
Firstly, the code has changed significantly such that the comment may no longer apply. Here's the updated code:
try
{
Task.WaitAny(task, cancelTask);
// Cancel whichever task has not finished.
cts.Cancel();
await task;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("\nCompleted successfully");
}
catch (OperationCanceledException taskCanceledException)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(
$"\nCancelled: { taskCanceledException.Message }");
}
finally
{
Console.ForegroundColor = originalColor;
}
Awaiting a cancelled task will indeed throw, and I count on this in order to display the cancelled message when the user cancels the activity.
Perhaps the issue is that I don't ever await the cancelTask
? If I did await cancelTask
I would always catch and suppress the exception because if task
runs to completion, I have to cancel the cancelTask
rather than continue waiting for a keyboard entry.
Is it necessary to always await all tasks even if you know they have completed and you don't care about capturing the exception?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just seems like you are then using exceptions for control flow (something discouraged in earlier chapters). If the goal is to simply display a message, wouldn't it be better to simply check the state of the token, and display the message?
Manually setting up a continuation on the task
would also seem like a preferable options to the exception handler.
cts.Cancel(); | ||
try { task.Wait(); } | ||
catch (AggregateException exception) | ||
await task; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It just seems like you are then using exceptions for control flow (something discouraged in earlier chapters). If the goal is to simply display a message, wouldn't it be better to simply check the state of the token, and display the message?
Manually setting up a continuation on the task
would also seem like a preferable options to the exception handler.
@Keboo, that is a great point. In this case the purpose of using exceptions is to demonstrate how control flows during cancellation. To not do so would be to miss the point that invoking |
Added an
ConsoleReadAsync()
method but would appreciate a second pair of eyes on the implementation. The purpose of the method is to provide a way to simulate cancelling a console.Read().