Task.Yield简单的异步方法实现优化吞吐量

Task.Yield将任务重新安排到线程池队列,并且可以执行等待线程的其他任务。当代码行第一次出现await Task.Yield();后,会重新排队到线程池,获取线程来执行后续的代码(此时不排除获取到当前调用的主线程,有可能获取到新的线程,如果获取到的是调用主线程仍然是以异步方式执行的,CPU时间片),且不会阻塞调用主线程,得到的效果就是主线程和异步线程是并行执行的,互不干扰。使用Task.Yield之后是为了优化线程调度,让最需要主线程处理的地方去处理,将主线程时间让给其他最需要的地方,然后在线程池排队重新获取处理线程。除了最极端的情况之外,线程的调度程序能够通过更改每个线程的执行来解决问题,允许每个短片时间运行,而不是运行每个操作完成。 最重要的是,通过使用线程池可以更有效地解决问题,线程池可以具有与可选项一样多的工作者,并以优化吞吐量的方式排队实际工作。

使用 async 和 await 对客户端应用带来的最大好处在于提高了响应能力。事实上,相比服务器将线程专用于接收到的每个请求,使用 async 和 await 能够使服务器多处理一个数量级的请求。
考虑使用两个服务器:一个运行异步代码,一个不运行异步代码。 鉴于本示例的目的,每个服务器只有 5 个可用于服务请求的线程。 请注意,这样小的数目仅可用于演示。
假设两个服务器都接收到 6 个并发请求。 每个请求执行一个 I/O 操作。 未运行异步代码的服务器必须对第 6 个请求排队,直到 5 个线程中的一个完成了绑定 I/O 的工作并编写了响应。 此时收到了第 20 个请求,由于队列过长,服务器可能会开始变慢。
运行有异步代码的服务器也需对第 6 个请求排队,但由于使用了 async 和 await,绑定了 I/O 的工作开始时,每个线程都会得到释放,无需等到工作结束。 收到第 20 个请求时,传入请求队列将变得很小(如果其中还有请求的话),且服务器不会变慢。

使用 async 和 await处理时,当主线程遇到await时会解除对调用主线程的占用,从新获取线程处理运行后面的代码,计算结果会在调用主线程上排队等待处理,最后主线程将返回执行得到结果

 static void Main(string[] args)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            int threadId2 = Thread.GetCurrentProcessorId();
            Console.WriteLine("外部:線程id=" + threadId2);

			bool guo = false;
            //調用異步
            var gg = GetIntMsAsync();
            //var gg = GetIntMsAsync().ConfigureAwait(false);         
			
			bool isFirst = false;
            AGAIN:
            if (isFirst)
            {
                stopwatch.Restart();
                //同步
                GetIntMs();
                guo = true;
            }
            isFirst = true;

            Console.WriteLine("GetIntMsAsync下面的代碼...");
            for (int i = 0; i < 10; i++)
            {
                //Console.WriteLine("mian裡面的方法" + i);
                WebClient webClient = new WebClient();
                string content = webClient.DownloadString("https://www.qq.com");
                Console.WriteLine($"{i + 1} mian下載的內容:" + content.Length);         
            } 
            stopwatch.Stop();
            long haoshi= stopwatch.ElapsedMilliseconds;
            Console.WriteLine("Hello World!執行耗時"+ haoshi);
			if (!guo)
            {
                goto AGAIN;
            }          
            Console.ReadKey();
}

 static int GetIntMs()
{
	int threadId = Thread.GetCurrentProcessorId();
	Console.WriteLine("\r\n同步執行開始:線程01 id=" + threadId);

	int km = 0;
	km = 8759 * 156;
	if (km > 1800)
	{
		km = 85200;
	}
	int i = 0;
	for (; i < 10; i++)
	{
		WebClient webClient = new WebClient();
		string content = webClient.DownloadString("https://www.baidu.com");
		Console.WriteLine($"{i + 1}下載的內容大小:" + content.Length);
	}
	return i;
}

static async Task<int> GetIntMsAsync()
{
	int threadId = Thread.GetCurrentProcessorId();
	Console.WriteLine("Task:線程01 id=" + threadId);
	await Task.Yield();
	int threadId5 = Thread.GetCurrentProcessorId();          
	Console.WriteLine("Yield Task后:線程02 id=" + threadId5);

	int i = 0;
	for (; i < 10; i++)
	{
		WebClient webClient = new WebClient();
		string content = webClient.DownloadString("https://www.baidu.com");
		Console.WriteLine($"{i + 1}下載的內容大小:" + content.Length);                
	}
	return i; 
}

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王焜棟琦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值