Асинхронная обработка помогает всякий раз, когда вы имеете дело с задержками, не связанными с ЦП, и хотите избежать тех, которые не охватывают безумное количество потоков (что плохо масштабируется - не должно быть слишком много потоков на ЦП, потому что потоки «дорогие» ресурсы, обильное переключение контекста может снизить производительность).
Таким образом, типичными получателями являются операции ввода-вывода, поскольку как диск, так и сеть "медленны" по сравнению с вычислительными усилиями, необходимыми для обработки данных. Поэтому, когда у вас может быть много параллельных потоков (сетевых и дисковых), вы должны использовать асинхронные операции для их обработки.
Тем не менее, правильное асинхронное программирование сложно, особенно без встроенной поддержки в новых компиляторах .NET.
Хорошая асинхронная копия должна использовать как минимум два буфера; один читает данные (асинхронный), а другой пишет данные (асинхронный) одновременно. Конечно, бездействующий считыватель запускается только после того, как считыватель завершает работу со своим блоком, а бездействующий считыватель запускается только тогда, когда имеется по меньшей мере резервный буфер (например, записывающее устройство завершило запись). Когда у вас есть только один буфер, между последовательными операциями чтения и записи будут разрывы, например это всегда будет «читать, писать, читать, ... писать» вместо «читать, читать + писать, читать + писать, ... писать».