Instantiating a Task in C# 7.0
Ever since C# 5.0 when the async/await pattern was introduced, the only supported return types were Task
Consider, for example, a function that returns the amount of space consumed by a directory.
public async Task<long> GetDirectorySize<T>(string path, string searchPattern)
{
if (!Directory.EnumerateFileSystemEntries(path, searchPattern).Any())
return 0;
else
return await Task.Run<long>(()=> Directory.GetFiles(path, searchPattern,
SearchOption.AllDirectories).Sum(t => (new FileInfo(t).Length)));
}
If the directory is empty, the known space is 0 and there is no need for an asynchronous thread to calculate the size. However, since Task
C# 7.0 introduces the ability to define custom return types on async methods. The key requirement is implementing the GetAwaiter method. The System.Threading.Tasks.ValueTask
public async ValueTask<long> GetDirectorySize<T>(string path, string searchPattern)
{
if (!Directory.EnumerateFileSystemEntries(path, searchPattern).Any())
return 0;
else
return await Task.Run<long>(()=> Directory.GetFiles(path, searchPattern,
SearchOption.AllDirectories).Sum(t => (new FileInfo(t).Length)));
}
Notice that no other changes are required.
Note that internally, if you open the method up with an IL disassembler like ILDasm.exe the signature still returns a Task
[AsyncStateMachine(typeof(CustomAsyncReturn.<GetDirectorySize>d__3<>))]
public Task<long> GetDirectorySize<T>(string path, string searchPattern)
{
// ...
}