起首,建一个 ASP.NET MVC WebAPI项目,在默许的控制器 values内里,增添两个要领:
// GET api/values?sleepTime=10 [HttpGet] public async Task<string> ExecuteAIO(int sleepTime) { await Task.Delay(sleepTime); return "Hello world,"+ sleepTime; } [HttpGet] // GET api/values?sleepTime2=10 public string ExecuteBIO(int sleepTime2) { System.Threading.Thread.Sleep(sleepTime2); return "Hello world," + sleepTime2; }
然后,竖立一个控制台顺序,来测试这个web API:
class Program { static void Main(string[] args) { Console.WriteLine("按任意键最先测试 WebAPI:http://localhost:62219/api/values?sleepTime={int}"); Console.Write("请输入线程数:"); int threadNum = 100; int.TryParse(Console.ReadLine(), out threadNum); while (Test(threadNum)) ; Console.ReadLine(); Console.ReadLine(); } private static bool Test(int TaskNumber) { Console.Write("请输入此API要领的就寝时刻(毫秒),输入非数字内容退出:"); string input = Console.ReadLine(); int SleepTime = 50; if (!int.TryParse(input, out SleepTime)) return false; HttpClient client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:62219/"); var result = client.GetStringAsync("api/values?sleepTime=" + input).Result; Console.WriteLine("Result:{0}", result); //int TaskNumber = 1000; Console.WriteLine("{0}次 BIO(同步)测试(就寝{1} 毫秒):", TaskNumber, SleepTime); System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); Task[] taskArr = new Task[TaskNumber]; for (int i = 0; i < TaskNumber; i++) { Task task = client.GetStringAsync("api/values?sleepTime2=" + SleepTime); taskArr[i] = task; } Task.WaitAll(taskArr); sw.Stop(); double useTime1 = sw.Elapsed.TotalSeconds; Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime1, TaskNumber/useTime1); sw.Reset(); Console.WriteLine("{0}次 AIO(异步)测试(就寝{1} 毫秒):", TaskNumber, SleepTime); sw.Start(); for (int i = 0; i < TaskNumber; i++) { Task task = client.GetStringAsync("api/values?sleepTime=" + SleepTime); taskArr[i] = task; } Task.WaitAll(taskArr); sw.Stop(); double useTime2 = sw.Elapsed.TotalSeconds; Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime2, TaskNumber / useTime2); return true; } }
View Code
实在主如果下面几行代码:
HttpClient client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:62219/");var result = client.GetStringAsync("api/values?sleepTime=" + input).Result;
注重,你能够须要运用Nuget增加下面这个包:
Microsoft.AspNet.WebApi.Client
末了,运转这个测试,效果以下:
按任意键最先测试 WebAPI:http://localhost:62219/api/values?sleepTime={int} 请输入线程数:1000 请输入此API要领的就寝时刻(毫秒),输入非数字内容退出:10 Result:"Hello world,10" 1000次 BIO(同步)测试(就寝10 毫秒): 耗时(秒):1.2860545,QPS: 777.57 1000次 AIO(异步)测试(就寝10 毫秒): 耗时(秒):0.4895946,QPS: 2042.51 请输入此API要领的就寝时刻(毫秒),输入非数字内容退出:100 Result:"Hello world,100" 1000次 BIO(同步)测试(就寝100 毫秒): 耗时(秒):8.2769307,QPS: 120.82 1000次 AIO(异步)测试(就寝100 毫秒): 耗时(秒):0.5435111,QPS: 1839.89
本来想尝试测试10000个线程,但报错了。
上面的测试效果,QPS并不高,但由于运用的是IISExpress,差别的Web服务器软件机能不相同,所以还得对照下历程内QPS效果,因而新建一个控制台顺序,代码以下:
class Program { static void Main(string[] args) { Console.WriteLine("按任意键最先测试 "); Console.Write("请输入线程数:"); int threadNum = 100; int.TryParse(Console.ReadLine(), out threadNum); while (Test(threadNum)) ; Console.ReadLine(); Console.ReadLine(); } private static bool Test(int TaskNumber) { Console.Write("请输入此API要领的就寝时刻(毫秒),输入非数字内容退出:"); string input = Console.ReadLine(); int SleepTime = 50; if (!int.TryParse(input, out SleepTime)) return false; var result = ExecuteAIO(SleepTime).Result; Console.WriteLine("Result:{0}", result); //int TaskNumber = 1000; Console.WriteLine("{0}次 BIO(同步)测试(就寝{1} 毫秒):", TaskNumber, SleepTime); System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); Task[] taskArr = new Task[TaskNumber]; for (int i = 0; i < TaskNumber; i++) { Task task = Task.Run<string>(()=> ExecuteBIO(SleepTime)); taskArr[i] = task; } Task.WaitAll(taskArr); sw.Stop(); double useTime1 = sw.Elapsed.TotalSeconds; Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime1, TaskNumber / useTime1); sw.Reset(); Console.WriteLine("{0}次 AIO(异步)测试(就寝{1} 毫秒):", TaskNumber, SleepTime); sw.Start(); for (int i = 0; i < TaskNumber; i++) { Task task = ExecuteAIO(SleepTime); taskArr[i] = task; } Task.WaitAll(taskArr); sw.Stop(); double useTime2 = sw.Elapsed.TotalSeconds; Console.WriteLine("耗时(秒):{0},QPS:{1,10:f2}", useTime2, TaskNumber / useTime2); return true; } public static async Task<string> ExecuteAIO(int sleepTime) { await Task.Delay(sleepTime); return "Hello world," + sleepTime; } public static string ExecuteBIO(int sleepTime2) { System.Threading.Thread.Sleep(sleepTime2); //不能在非异步要领内里运用 Task.Delay,不然能够死锁 //Task.Delay(sleepTime2).Wait(); return "Hello world," + sleepTime2; } }
View Code
注重,症结代码只要下面两个要领:
public static async Task<string> ExecuteAIO(int sleepTime) { await Task.Delay(sleepTime); return "Hello world," + sleepTime; } public static string ExecuteBIO(int sleepTime2) { System.Threading.Thread.Sleep(sleepTime2); //不能在非异步要领内里运用 Task.Delay,不然能够死锁 //Task.Delay(sleepTime2).Wait(); return "Hello world," + sleepTime2; }
这两个要领跟WebAPI的测试要领代码是一样的,然则挪用代码轻微差别:
同步挪用:
Task[] taskArr = new Task[TaskNumber]; for (int i = 0; i < TaskNumber; i++) { Task task = Task.Run<string>(()=> ExecuteBIO(SleepTime)); taskArr[i] = task; } Task.WaitAll(taskArr);
异步挪用:
for (int i = 0; i < TaskNumber; i++) { Task task = ExecuteAIO(SleepTime); taskArr[i] = task; } Task.WaitAll(taskArr);
可见,这里测试的时刻,同步和异步挪用,客户端代码都是运用的多线程,重要的区分就是异步要领运用了 async/await 语句。
下面黑白Web的历程内异步多线程和同步多线程的效果:
请输入线程数:1000 请输入此API要领的就寝时刻(毫秒),输入非数字内容退出:10 Result:Hello world,10 1000次 BIO(同步)测试(就寝10 毫秒): 耗时(秒):1.3031966,QPS: 767.34 1000次 AIO(异步)测试(就寝10 毫秒): 耗时(秒):0.026441,QPS: 37820.05 请输入此API要领的就寝时刻(毫秒),输入非数字内容退出:100 Result:Hello world,100 1000次 BIO(同步)测试(就寝100 毫秒): 耗时(秒):9.8502858,QPS: 101.52 1000次 AIO(异步)测试(就寝100 毫秒): 耗时(秒):0.1149469,QPS: 8699.67 请输入线程数:10000 请输入此API要领的就寝时刻(毫秒),输入非数字内容退出:10 Result:Hello world,10 10000次 BIO(同步)测试(就寝10 毫秒): 耗时(秒):7.7966125,QPS: 1282.61 10000次 AIO(异步)测试(就寝10 毫秒): 耗时(秒):0.083922,QPS: 119158.27 请输入此API要领的就寝时刻(毫秒),输入非数字内容退出:100 Result:Hello world,100 10000次 BIO(同步)测试(就寝100 毫秒): 耗时(秒):34.3646036,QPS: 291.00 10000次 AIO(异步)测试(就寝100 毫秒): 耗时(秒):0.1721833,QPS: 58077.64
效果示意,.NET顺序开启10000个使命(不是10000个原生线程,须要斟酌线程池线程),异步要领的QPS超过了10万,而同步要领只要1000多点,机能差异照样很大的。
注:以上测试效果的测试环境是
Intel i7-4790K CPU,4核8线程,内存 16GB,Win10 企业版
以上就是.net中关于异步机能测试的示例代码的细致内容,更多请关注ki4网别的相干文章!