Вы можете использовать таймер, который тикает с интервалом в 1 секунду, и подсчитывать загруженные байты между двумя тиками.
Следующий код является неполированным, он не форматирует скорость до МБ / с, и таймер продолжает тикать после завершения загрузки, а случай исключения, такой как отмена / перезапуск, не обрабатывается, я просто даю вам представление о том, как использовать таймер и счетчик, чтобы сделать расчет.
DispatcherTimer timer;
ulong bytesReceivedAtLastTick;
private async void StartDownload()
{
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(source, destinationFile);
timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) };
timer.Tick += (s, e) => {
var bytesReceivedAtThisTick = download.Progress.BytesReceived;
var bytesPerSecond = bytesReceivedAtThisTick - bytesReceivedAtLastTick;
Log($"Download speed: {bytesPerSecond} B/s");
bytesReceivedAtLastTick = bytesReceivedAtThisTick;
};
timer.Start();
await download.StartAsync().AsTask(cts.Token, progressCallback);
}