Can the C# compiler distinguish between I/O bound and computational tasks?

Consider a snippet of code such as this:

public async Task<Bitmap> DownloadDataAndRenderImageAsync(
    CancellationToken cancellationToken)
{
    var imageData = await DownloadImageDataAsync(cancellationToken);
    return await RenderAsync(imageData, cancellationToken);
}

The first of the steps in this method is I/O bound work where as the second, computational.

When we rely on the compiler to generate the right task-based code for this asynchronous operation, what does the compiler do?

Specifically, does it know that the first one is I/O bound so it must use the TaskCompletionSource<T> class so that there is no affinity between a thread and the task, and that for the second one, it can use any of the methods such as Run or StartNew or Start to schedule the task on a thread-pool thread?

Jon Skeet
people
quotationmark

No. In the example you've given, the compiler will only use TaskCompletionSource<T> (indirectly) for the overall asynchronous operation (DownloadDataAndRenderImageAsync). It's up to the two methods that are called to decide how they're going to return the relevant task.

Maybe DownloadImageDataAsync is itself an async method which delegates down to some more async I/O. Maybe RenderAsync calls Task.Run. Those are both implementation details that the compiler doesn't care about at all when compiling DownloadDataAndRenderImageAsync.

people

See more on this question at Stackoverflow