java同步调用异步方法_关于同步方法里面调用异步方法的探究

本文探讨了在同步方法中调用异步方法可能导致的问题,特别是线程死锁和线程饥饿。通过示例代码,展示了同步调用`.Result`或`.Wait()`如何引发死锁,特别是在高并发情况下。解决方案包括避免这种做法,以及使用`TaskCreationOptions.LongRunning`创建专用线程以避免线程池资源争抢。
摘要由CSDN通过智能技术生成

##前言

我在写代码的时候(.net core)有时候会碰到void方法里,调用async方法并且Wait,而且我还看到别人这么写了。而且我这么写的时候,编译器没有提示任何警告。但是看了dudu的文章:一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相 了解了,这样写是有问题的。但是为什么会有问题呢?我又阅读了dudu文章里提到的一篇博文:.NET Threadpool starvation, and how queuing makes it worse 加上自己亲手实验,写下自己的理解,算是对dudu博文的一个补充和丰富吧。

##同步方法里调用异步方法

同步方法里调用异步方法,一种是wait() 一种是不wait()

void fun()

{

funAsync.Wait();

funAsync();

}

这两种场景都没有编译错误。

首先我们来看一下,在 void里调用 async 方法,并且要等待async的结果出来之后,才能进行后续的操作。

using System;

using System.Threading;

using System.Threading.Tasks;

namespace ConsoleTool2

{

class Program

{

static void Main(string[] args)

{

Producer();

}

static void Producer()

{

var result = Process().Result;

//或者

//Process().Wait();

}

static async Task Process()

{

await Task.Run(() =>

{

Thread.Sleep(1000);

});

Console.WriteLine("Ended - " + DateTime.Now.ToLongTimeString());

return true;

}

}

}

咱们看这个Producer,这是一个void方法,里面调用了异步方法Process(),其中Process()是一个执行1秒的异步方法,调用的方式是Process().Result 或者Process().Wait()。咱们来运行一遍。

3013fecd2d2849b61757c0b535ab318b.png

没有任何问题。看起来,这样写完全没有问题啊,不

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值