gpt4 book ai didi

c# - 我可以异步运行同步代码以获得性能吗?

转载 作者:行者123 更新时间:2023-12-03 13:18:34 26 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





What is the purpose of "return await" in C#?

(8 个回答)


1年前关闭。




我已经阅读了很多讨论在 C# 中使用 Async/Await 的论坛、教程和博客。我读得越多,它就越困惑。
此外,人们主要谈论在同步方法中调用异步的东西,而不是在异步方法中调用同步的东西。
由于我是一名初级开发人员并且对异步编程没有太多经验,因此我将在这里发布一个新问题并希望得到一些启发。
考虑一下:
我有一个 Web API 端点,可以进行一些计算和模型构建并返回一些数据。

public async Task<JsonResult> GetData()
{
Task<Data> stuff1Task = CalculateStuff1();
Task<Data> stuff2Task = CalculateStuff2();
Task<Data> stuff3Task = CalculateStuff3();

return Json(
new
{
stuff1 = await stuff1Task,
stuff2 = await stuff2Task,
stuff3 = await stuff3Task
}, JsonRequestBehavior.AllowGet
);
}

private async Task<Data> CalculateStuff1()
{
return await SomeAsyncCalculation();
}

private async Task<Data> CalculateStuff2()
{
return SomeSyncCalculation();
}

private async Task<Data> CalculateStuff3()
{
Task<Data> dataTask1 = SomeAsyncCalculation();
Task<Data> dataTask2 = AnotherAsyncCalculation();

Data data1 = await dataTask1;
Data data2 = await dataTask2;

Data combindedData = SyncMethodToCombineData(data1, data2);

return combindedData;
}
为什么我考虑混合异步和同步代码是为了获得更好的性能。
在这种情况下,让我们假装 SomeAsyncCalculation() , SomeSyncCalculation()AnotherAsyncCalculation()是相当昂贵的方法。我的目标是让这些方法在某种程度上并行运行,以获得更快的响应时间。
我知道最好是“一路异步”,但让我们说实话,重建一半的项目并不总是优先事项或可能性。
此外,我可能与不支持异步操作的其他系统进行了一些集成。
我收到此警告 CalculateStuff2()增加了困惑。 :

this async method lacks 'await' operators and will run synchronously


据我了解,“async”关键字仅适用于包装方法并允许我使用 await 关键字。它还允许我只返回数据,我不需要管理任务返回结果。它还处理异常。 Task<TResult>返回类型是使该方法在不同线程上执行的原因(尽管不能保证它将在不同线程上执行)。
结论性问题:
1.请问 的异步方法不使用等待 ( CalculateStuff2() )在它自己的线程上同步运行(如果它在另一个线程上运行,因为它是一个 Task )还是会在 API 调用的主线程中运行,并且无论如何总是阻塞它?
2. 使用 是不是不好?异步 没有 等待只是为了有一个开箱即用的包装精美的任务方法?

最佳答案

你不需要 async同步方法。 async生成状态机,这是一种冗余,以防您不需要 await .
考虑这个稍微优化的例子。

public async Task<JsonResult> GetData()
{
Task<Data> stuff1Task = CalculateStuff1();
Task<Data> stuff3Task = CalculateStuff3();
Data stuff2data = CalculateStuff2(); // run sync method after launching async ones

return Json(new
{
stuff1 = await stuff1Task,
stuff2 = stuff2data,
stuff3 = await stuff3Task
}, JsonRequestBehavior.AllowGet);
}

private Task<Data> CalculateStuff1() // optimized
{
return SomeAsyncCalculation();
}

private Data CalculateStuff2()
{
return SomeSyncCalculation();
}

private async Task<Data> CalculateStuff3()
{
//use combinator to simplify the code
Data[] data = await Task.WhenAll(SomeAsyncCalculation(), AnotherAsyncCalculation());

Data combindedData = SyncMethodToCombineData(data[0], data[1]);

return combindedData;
}
还要考虑区分 CPU-bound 和 IO-bound 操作,查看 this article .根据您要启动的具体内容,有不同的异步方法。
直接回答
  1. Will the async method that does not use await (CalculateStuff2()) run synchronously on it's own thread (if it runs on another thread because it is a Task) or will it run in the main thread of the API call, and always block it no matter what?

是的,它将在调用者线程上同步运行。如果你想在自己的线程上运行一些同步方法,使用 Task.Run() :
Task<Data> stuff2Task = Task.Run(() => CalculateStuff2());
然后 await它。
  1. Is it bad practice to use async without await just to have a nicely wrapped task method out of the box?

是的,这是不好的做法。冗余状态机产生的开销在这种情况下毫无值(value)。

关于c# - 我可以异步运行同步代码以获得性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63133486/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com