为什么我的程序的异步版本比同步版本慢?

时间:2016-04-26 14:21:49

标签: c# asynchronous

我刚刚对同步和异步进行了一些测试,并编写了以下程序进行测试。 也许我做错了什么或者我没有正确地理解异步,

我发现同步版本需要318 ms而异步需要18764 ms

static void Main(string[] args)
        {
            int num = 25;
            Task[] tasks = new Task[num];

            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i < num; i++)
            {
                int c = i;
                tasks[i] = Task.Factory.StartNew(() => { RunAsync(c).Wait(); });
            }
            Task.WaitAll(tasks);
            sw.Stop();
            Console.WriteLine($"FINISHED (Async) in {sw.ElapsedMilliseconds} ms");

            sw.Start();
            for (int i = 0; i < num; i++)
            {
                RunSync(i + 100);
            }
            sw.Stop();
            Console.WriteLine($"FINISHED (Sync) in {sw.ElapsedMilliseconds} ms");

            Console.ReadLine();
        }

        private static void RunSync(int index)
        {
            FileStream stream = new FileStream(@"c:\\test\ff\tests.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
            string pp = Path.Combine(@"c:\\test\ff", "threadS-" + index + ".txt");
            FileStream sw = File.Create(pp);
            byte[] buffer = new byte[1024];
            long bytesRead = 0;
            long bytestoRead = stream.Length;
            try
            {
                while (bytesRead < bytestoRead)
                {
                    int count = stream.Read(buffer, 0, buffer.Length);
                    bytesRead += count;
                    sw.Write(buffer, 0, count);
                }
            }
            finally
            {
                sw.Close();
                stream.Close();
            }
        }

        private async static Task RunAsync(int index)
        {
            FileStream stream = new FileStream(@"c:\\test\ff\tests.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
            int tId = Thread.CurrentThread.ManagedThreadId;

            string pp = Path.Combine(@"c:\\test\ff", "thread-" + index + ".txt");
            FileStream sw = File.Create(pp);
            byte[] buffer = new byte[1024];
            long bytesRead = 0;
            long bytestoRead = stream.Length;
            try
            {
                while (bytesRead < bytestoRead)
                {
                    int count = await stream.ReadAsync(buffer, 0, buffer.Length);
                    bytesRead += count;
                    await sw.WriteAsync(buffer, 0, count);
                }
            }
            finally
            {
                sw.Close();
                stream.Close();
            }
        }

2 个答案:

答案 0 :(得分:2)

有些事情你做得不正确,而且你开始时是错误的前提。所以让我从错误的前提开始:

  

async / await旨在让应用响应或在多个核心之间分配工作 - 它们不一定能提高运行时性能。

换句话说,当您查看整体吞吐量时,您可能会处理比连续处理工作单元更多的工作。但是,该阈值将随着在任何给定时间完成的工作量而变化。

正确处理async / await意味着不要将较旧的Task功能与较新的支持混合使用。这会丢失异步函数的所有好处并增加同步开销。 当您要等待后台工作完成时,切勿致电Task.Wait()Task.WaitAll(tasks)这会强制一个线程完全暂停并且无响应,直到后台工作完成。

您想进行以下调整:

        for (int i = 0; i < num; i++)
        {
            int c = i;
            tasks[i] = RunAsync(c);
        }
        await Task.WhenAll(tasks);

由于您无法使Main函数成为async,您可能必须将该调用移至另一个函数,以便您可以执行async / await协议。

答案 1 :(得分:1)

异步调用不一定有保证的执行时间。当调度程序决定资源可用时,它们将被调用。因此,完成它们的等待时间可能高于同步调用同一方法,因为保证在被调用时实时执行同步调用。