Is finally executed only after a returned Task is awaited?

Viewed 271

I have an asnyc method which returns a task and is doing some cleanup work in a finally block:

public Task<byte[]> MyFunction() {
   string filename = CreateFile();
   try {
      return File.ReadAllBytesAsync(filename);
   } finally {
      File.Delete(filename);
   }
}

Is it guaranteed, that the finally block will only be called after the return value has been awaited, or can this create a race condition where the file gets deleted before it is completely read?

2 Answers

There is no guarantee that the file will not be created. You need to await the call (notice also the async keyword):

public async Task<byte[]> MyFunction() {
   string filename;
   try {
      filename = CreateFile();
      return await File.ReadAllBytesAsync(filename);
   } finally {
      File.Delete(filename);
   }
}

If the call is not awaited, then you return while still running the task and it will most likely not complete before the file is deleted. This would definitely be a race condition.

Not only will it not await anything, it won't compile, either. You need to take a few steps:

  1. Make the method async
  2. Actually await the result of File.ReadAllBytesAsync
  3. Declare the filename variable outside of the try-finally block
Related