Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否过度使用异步等待?_C#_.net_Async Await_Roslyn - Fatal编程技术网

C# 是否过度使用异步等待?

C# 是否过度使用异步等待?,c#,.net,async-await,roslyn,C#,.net,Async Await,Roslyn,我想知道我是否在代码中使用了async和wait,以及这样做是否会造成(性能)损失 我经常做的事: static void Main() { var result = Task<int>.Run (()=> S1Async(1)).Result; Console.WriteLine(result); } static async Task<int> WrapperAsync(Func<int, Task<int>> func

我想知道我是否在代码中使用了
async
wait
,以及这样做是否会造成(性能)损失

我经常做的事:

static void Main()
{
    var result = Task<int>.Run (()=> S1Async(1)).Result;
    Console.WriteLine(result);
}

static async Task<int> WrapperAsync(Func<int, Task<int>> func) => await func(2);
static async Task<int> S1Async(int x) => await WrapperAsync(async t=> await S2Async(x * t));
static async Task<int> S2Async(int x) => await WrapperAsync(async t=> await S3Async(x * t));
static async Task<int> S3Async(int x) => await WrapperAsync(async t=> await S4Async(x * t));
static async Task<int> S4Async(int x) => await Task.FromResult(x * 10);
static void Main()
{
var result=Task.Run(()=>S1Async(1)).result;
控制台写入线(结果);
}
静态异步任务包装器异步(Func Func)=>wait Func(2);
静态异步任务S1Async(intx)=>await WrapperAsync(async t=>await S2Async(x*t));
静态异步任务S2Async(intx)=>await WrapperAsync(async t=>await S3Async(x*t));
静态异步任务S3Async(intx)=>await WrapperAsync(async t=>await S4Async(x*t));
静态异步任务S4Async(intx)=>等待任务.FromResult(x*10);
我认为可以跳过异步等待,并且此代码类似:

static void Main()
{
    var result = Task<int>.Run(() => S1Async(1)).Result;
    Console.WriteLine(result);
}

static Task<int> WrapperAsync(Func<int, Task<int>> func) => func(2);
static Task<int> S1Async(int x) => WrapperAsync(t => S2Async(x * t));
static Task<int> S2Async(int x) => WrapperAsync(t => S3Async(x * t));
static Task<int> S3Async(int x) => WrapperAsync(t => S4Async(x * t));
static Task<int> S4Async(int x) => Task.FromResult(x * 10);
static void Main()
{
var result=Task.Run(()=>S1Async(1)).result;
控制台写入线(结果);
}
静态任务包装器异步(Func Func)=>Func(2);
静态任务S1Async(intx)=>WrapperAsync(t=>S2Async(x*t));
静态任务S2Async(intx)=>wrappersync(t=>S3Async(x*t));
静态任务S3Async(intx)=>wrappersync(t=>S4Async(x*t));
静态任务S4Async(intx)=>Task.FromResult(x*10);
当任务嵌套在每个级别只有一个任务时,跳过异步/等待是否安全


两个代码示例在LinqPad中给出了相同的结果,因此我假设它们是相似的,但可能有一些副作用我应该注意到?

简短的回答是:是的,在这种情况下可以跳过它们,是的,会有性能损失

当您的方法只需等待一次并立即返回时,如下所示:

async任务fooancy()
{
/* ... */
等待同步();
}
那么它就相当于写:

Task fooancy()
{
/* ... */
返回BarAsync();
}
async
的含义是(从
fooancy
的角度来看):好的,操作
BarAsync
可能需要一段时间才能完成,因此如果我们从中得到一个未完成的
任务
,让我保存当前状态并将控制流返回给调用方。一旦
任务
完成,我想重新开始状态并继续我一直在做的事情

在这种情况下,很明显,
BarAsync
任务
完成后不会执行额外的工作,因此您可以将该
任务
返回给调用者,因为实际上
fooancy
完成的时间与
任务
完成的时间完全相同。不需要保存任何状态或计划继续

当我们讨论单个调用时,这种方法的开销并不巨大,但是如果您多次调用这种方法,您可能会感到影响。当您将方法声明为
async
时,编译器必须设置整个
async
基础结构-状态机、连续调度、整个包。因此,一般来说:如果您可以将方法简化为非
异步
,而只是返回另一个
任务
,那么这样做是值得的

作为旁注:您当然不需要将
S1Async
调用包装到
任务中。运行
,您就不必自C#7.1以来同步阻塞
。你可以写:

static async Task Main()
{
var结果=等待S1Async(1);
控制台写入线(结果);
}

我想说,这段代码的最大问题是将异步等待与阻塞(使用
Result
Wait
)混合在一起,如果使用不当,这种做法可能会导致死锁。不使用async await,而是返回任务是可以的,只要您不在try块中执行此操作,因为如果您不
await
,则在您离开try块后会引发异常。这是一种惩罚吗?你的问题是,如果这变得越来越慢,那么执行一切都是同步的吗?5个线程互相等待,你知道你在做什么…这没什么错。线程池正在处理,您一次启动的线程不会太多(但阈值超过100)。您可以使用2个线程使自己陷入死锁,而使用不小心编程的机会可能会增加到200个线程。在单核CPU上,async对同步执行的惩罚总是很小。但是单核CPU现在只存在于虚拟机上。在这里玩一下:你会看到两者之间的区别。差异的实际成本取决于您正在进行的计算,但如果“有用”代码与“开销”之间的关系不好,则差异可能会很大,