调用同步代码的选项

我觉得我已经阅读了数以千计的 SO 问题和博客文章以及关于这些东西的 MSDN 文章,但我仍然没有完全“理解”它。所以请帮帮我。


在我的工作中,我们有一个 ASP.NET 应用程序,它必须从同步方法中获取数据。我无法控制这种方法,也不知道它是如何实现的。


我有一个异步控制器方法,它正在调用 3 个其他异步服务,我可以“一路向下”使用异步(是的!)。但最后一个不是异步的,而且可能永远不会。更糟糕的是,它需要最长的时间。我希望能够为所有服务启动任务,并等待它们。从我能够拼凑起来的情况来看,我有以下选项可供我使用,我想我了解大部分后果,但在必要时希望得到确认和澄清。


所以,给定方法:


public async Task<Thing> GetThing()

{

    var task1 = GetProp1Async(); // etc.

    var syncResult = ......


    myThing.Prop1 = await task1;

    myThing.SyncProp = ....... 

    return myThing;

}

我填写这些点的选项可能是:


选项1:


只需同步调用该方法。这将阻塞我当前的线程。我的其他任务都可以运行,我可以稍后等待它们,但我将在这里阻塞,在我的异步方法中。


var syncResult = GetSyncResult();

选项 2:


使用 Task.Run().Result。我知道这根本不理想,因为我会生成一个新线程,同时也会阻塞我的原始线程,我认为这是最糟糕的情况,对吧?但是,我不会遇到死锁问题,因为我正在强制创建一个新线程,对吗?


var syncResult = Task.Run(() => GetSyncResult()).Result;

选项 3:


我认为这是最好的选择?我的异步代码不会阻塞线程,但我仍在生成一个新线程来执行同步工作。所以,这感觉就像是净零增益。我仍然有 1 个线程在做事情,可能还在等待,但这仍然可能是我最好的选择?


var syncResult = await Task.Run(() => GetSyncResult());

选项 4:


我仍然不明白 ConfigureAwait(false),但我可以尝试一下。这对我有什么好处?似乎有些帖子说“在所有地方都这样做!” 有人说“不要这样做以避免死锁”。其他人说,如果你这样做,就“一路向下”。好吧,我不知道 GetSyncResult() 做了什么,所以我不知道它是否在幕后调用了任何异步内容(我的意思是,它可能没有,但我不确定)。那么它会回来咬我吗?


var syncResult = await Task.Run(() => GetSyncResult()).ConfigureAwait(false);

那么我最好的选择是什么?我错过了任何选择吗?更糟糕的是,我错过了最佳选择吗?


我知道这些问题已经被问到并得到了死亡的回答,但是,我只是没有把我的点联系起来,我肯定需要一些帮助。


杨__羊羊
浏览 174回答 1
1回答
打开App,查看更多内容
随时随地看视频慕课网APP