我只是对同步与异步进行一些测试,并编写了以下程序来测试。 也许我做错了什么,或者我只是没有正确理解异步,
我看到我的同步版本需要 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();
}
}
最佳答案
您做错了几件事,而且您一开始的前提是错误的。那么让我从错误的前提开始:
async
/await
are designed to keep an app responsive or distribute work among many cores--they don't necessarily improve run-time performance.
换句话说,当您查看总体吞吐量时,您可能会处理比串行处理工作单元更多的工作。但是,该阈值将根据任何给定时间完成的工作量而变化。
正确处理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 协议(protocol)。
关于c# - 为什么我的程序的异步版本比同步版本慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36867744/