I have 3 files, each 1 million rows long and I'm reading them line by line. No processing, just reading as I'm just trialling things out.
If I do this synchronously it takes 1 second. If I switch to using Threads, one for each file, it is slightly quicker (code not below, but I simply created a new Thread and started it for each file).
When I change to async, it is taking 40 times as long at 40 seconds. If I add in any work to do actual processing, I cannot see how I'd ever use async over synchronous or if I wanted a responsive application using Threads.
Or am I doing something fundamentally wrong with this code and not as async was intended?
Thanks.
class AsyncTestIOBound { Stopwatch sw = new Stopwatch(); internal void Tests() { DoSynchronous(); DoASynchronous(); } #region sync private void DoSynchronous() { sw.Restart(); var start = sw.ElapsedMilliseconds; Console.WriteLine($"Starting Sync Test"); DoSync("Addresses", "SampleLargeFile1.txt"); DoSync("routes ", "SampleLargeFile2.txt"); DoSync("Equipment", "SampleLargeFile3.txt"); sw.Stop(); Console.WriteLine($"Ended Sync Test. Took {(sw.ElapsedMilliseconds - start)} mseconds"); Console.ReadKey(); } private long DoSync(string v, string filename) { string line; long counter = 0; using (StreamReader file = new StreamReader(filename)) { while ((line = file.ReadLine()) != null) { counter++; } } Console.WriteLine($"{v}: T{Thread.CurrentThread.ManagedThreadId}: Lines: {counter}"); return counter; } #endregion #region async private void DoASynchronous() { sw.Restart(); var start = sw.ElapsedMilliseconds; Console.WriteLine($"Starting Sync Test"); Task a=DoASync("Addresses", "SampleLargeFile1.txt"); Task b=DoASync("routes ", "SampleLargeFile2.txt"); Task c=DoASync("Equipment", "SampleLargeFile3.txt"); Task.WaitAll(a, b, c); sw.Stop(); Console.WriteLine($"Ended Sync Test. Took {(sw.ElapsedMilliseconds - start)} mseconds"); Console.ReadKey(); } private async Task<long> DoASync(string v, string filename) { string line; long counter = 0; using (StreamReader file = new StreamReader(filename)) { while ((line = await file.ReadLineAsync()) != null) { counter++; } } Console.WriteLine($"{v}: T{Thread.CurrentThread.ManagedThreadId}: Lines: {counter}"); return counter; } #endregion }
await file.ReadLineAsync- you still accessing one source of data, which can be accessed only one by one. So in async approach you just addingawaitoverhead.trueforisAsyncorFileOptions.Asynchronous. Otherwise (i.e., in this code), "asynchronous" code likeReadLineAsyncis actually just doing synchronous work on a thread pool thread. That said, concurrently accessing a limited resource (HDD) is probably going to hurt performance, as the other answers point out; so even if this was truly asynchronous, it wouldn't be faster.