I am learning async await operations and have found a very useful article.
I consider the the last code snippet from this article:
public async Task ProcessWriteMult(CancellationToken cancellationToken)
{
string folder = @"tempfolder\";
List<Task> tasks = new List<Task>();
List<FileStream> sourceStreams = new List<FileStream>();
try
{
for (int index = 1; index <= 10; index++)
{
string text = "In file " + index.ToString() + "\r\n";
string fileName = "thefile" + index.ToString("00") + ".txt";
string filePath = folder + fileName;
byte[] encodedText = Encoding.Unicode.GetBytes(text);
FileStream sourceStream = new FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true);
Task theTask = sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
sourceStreams.Add(sourceStream);
tasks.Add(theTask);
}
await Task.WhenAll(tasks);
}
finally
{
foreach (FileStream sourceStream in sourceStreams)
{
sourceStream.Close();
}
}
}
I have tried some code to cancel tasks, however, imho, these are very ugly attempts. In this attempt my program flow waits for pressing key by user, but I would like this code to work till user press Esc button, like event:
if(Console.ReadKey().Key==System.ConsoleKey.Escape)
cts.Cancel();
How can I properly cancel by Escape key?
UPDATE:
I've inserted this code:
static void Main(string[] args)
{
var cts=new CancellationTokenSource();
ProcessWriteMult(cts);
if(Console.ReadKey().Key == System.ConsoleKey.Escape)
cts.Cancel();
}
However, this code does not cancel method ProcessWriteMult(cts)
.
What am I doing wrong?
First off, don't use
async void
. I'm not sure why the MSDN example encourages bad practice, but still, don't do that. Usingasync void
means you're method is "fire and forget", it can't be asynchronously waited, and any exception that happens inside it will be thrown on a thread-pool thread. Instead, useasync Task
.Now, .NET 4.0 introduced the concept of
CancellationTokenSource
, which helps you do cooperative cancellation. This means that you have to monitor on the token in order to know someone from "the outside" requested cancellation. This can be done as follows:It could be that by the time you press escape, the method already finished executing. You can test this by awaiting
Task.Delay
on a certain interval (lets say, 5 seconds), and only then monitoring the cancellation token.