- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想弄清楚是否应该在顶级请求上使用 ConfigureAwait(false)。从该主题的某种权威阅读这篇文章:
http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
......他推荐这样的东西:
public async Task<JsonResult> MyControllerAction(...)
{
try
{
var report = await _adapter.GetReportAsync();
return Json(report, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json("myerror", JsonRequestBehavior.AllowGet); // really slow without configure await
}
}
public async Task<TodaysActivityRawSummary> GetReportAsync()
{
var data = await GetData().ConfigureAwait(false);
return data
}
最佳答案
它是一个高流量的网站吗?一种可能的解释可能是您遇到了 ThreadPool
不使用时饥饿 ConfigureAwait(false)
.无 ConfigureAwait(false)
, await
继续通过 AspNetSynchronizationContext.Post
排队,该实现归结为 this :
Task newTask = _lastScheduledTask.ContinueWith(_ => SafeWrapCallback(action));
_lastScheduledTask = newTask; // the newly-created task is now the last one
ContinueWith
在没有
TaskContinuationOptions.ExecuteSynchronously
的情况下使用(我推测,使延续真正异步并减少低堆栈情况的机会)。因此,它从
ThreadPool
获取一个空线程。继续执行。理论上,它可能恰好与
await
的先行任务所在的线程相同。已经完成,但很可能它会是一个不同的线程。
GetReportAsync
操作很可能在一个 IOCP 线程子池上完成,它似乎并不饿。 OTOH,
ContinueWith
继续在工作线程子池上运行,这在您的情况下似乎很饿。
ConfigureAwait(false)
的情况下不会发生这种情况一直使用。在这种情况下,所有
await
continuation 将在相应的先行任务已经结束的相同线程上同步运行,无论是 IOCP 还是工作线程。
ConfigureAwait(false)
.我希望这个数字在
ConfigureAwait(false)
时会更大未使用:
catch (Exception ex)
{
Log("Total number of threads in use={0}",
Process.GetCurrentProcess().Threads.Count);
return Json("myerror", JsonRequestBehavior.AllowGet); // really slow without configure await
}
<configuration>
<system.web>
<applicationPool
maxConcurrentRequestsPerCPU="6000"
maxConcurrentThreadsPerCPU="0"
requestQueueLimit="6000" />
</system.web>
</configuration>
I realized I was missing a ContinueAwait somewhere in my chain. Now it works fine when throwing an exception even when the top level doesn't use ConfigureAwait(false).
Task.Result
、
Task.Wait
、
WaitHandle.WaitOne
,也许添加了一些超时逻辑)。你找过那些吗?试试
Task.Run
来自此更新底部的建议。此外,我仍然会进行线程计数诊断以排除线程池饥饿/口吃。
So are you saying that if I DO use ContinueAwait even at the top level I lose the whole benefit of the async?
async
是为了避免在等待时阻塞线程,无论
ContinueAwait(false)
的附加值如何,该目标都可以实现。 .
ConfigureAwait(false)
可能会引入冗余上下文切换(通常意味着线程切换),如果线程池在其容量下工作,这可能是 ASP.NET 中的问题。尽管如此,就服务器可扩展性而言,冗余线程切换仍然优于阻塞线程。
ContinueAwait(false)
也可能导致冗余上下文切换,特别是如果它在整个调用链中的使用不一致。
ContinueAwait(false)
也经常被误用作为解决由
blocking on asynchronous code 引起的死锁的补救措施.这就是为什么我在上面建议在所有代码库中寻找那些阻塞构造的原因。
However the question still remains as posted as to whether or not ConfigureAwait(false) should be used at the top level.
async void
的框架代码。事件处理程序。如果是 ASP.NET,则是异步 Controller 的
BeginExecute
.确保在异步任务完成后,延续(如果有)在正确的同步上下文中运行是该 super 顶级代码的责任。这不是您的任务代码的责任。例如,可能根本没有延续,就像一个即发即忘的
async void
事件处理程序;你为什么要在这样的处理程序中恢复上下文?
await
的上下文继续,请使用
ConfigureAwait(false)
你尽快做。
ConfigureAwait(false)
的第 3 方库。不一致,你可能想用
Task.Run
结束通话或类似
WithNoContext
.你这样做是为了提前从上下文中获取异步调用链:
var report = await Task.Run(() =>
_adapter.GetReportAsync()).ConfigureAwait(false);
return Json(report, JsonRequestBehavior.AllowGet);
ConfigureAwait(false)
可能会为您节省更多的线程切换。内部使用不一致
GetReportAsync
或其任何子调用。它还可以作为由调用链中的那些阻塞构造(如果有)引起的潜在死锁的解决方法。
HttpContext.Current
不是唯一与
AspNetSynchronizationContext
一起流动的静态属性.例如,还有
Thread.CurrentThread.CurrentCulture
.确保你真的不关心失去上下文。
For brownie points, maybe you can explain the effects of ConfigureAwait(false)... What context isn't preserved.. Is it just the HttpContext or the local variables of the class object, etc.?
async
的所有局部变量方法在
await
中保留,以及隐含的
this
引用 - 按设计。它们实际上被捕获到编译器生成的异步状态机结构中,因此从技术上讲,它们并不驻留在当前线程的堆栈中。在某种程度上,它类似于 C# 委托(delegate)捕获局部变量的方式。事实上,一个
await
连续回调本身就是一个传递给
ICriticalNotifyCompletion.UnsafeOnCompleted
的委托(delegate)(由正在等待的对象实现;对于
Task
,它是
TaskAwaiter
;对于
ConfigureAwait
,它是
ConfiguredTaskAwaitable
)。
ConfigureAwait(false)
时),唯一保留的全局状态是由
ExecutionContext
流动的状态。 . Microsoft 的 Stephen Toub 对此发表了一篇很棒的文章:
"ExecutionContext vs SynchronizationContext" .他提到
SecurityContext
和
Thread.CurrentPrincipal
,这对安全至关重要。除此之外,我不知道
ExecutionContext
流过的任何正式记录和完整的全局状态属性列表。 .
ExecutionContext.Capture
source了解更多关于究竟是什么流动,但你不应该依赖于这个特定的实现。相反,您始终可以创建自己的全局状态流逻辑,使用类似 Stephen Cleary 的
AsyncLocal
之类的东西。 (或 .NET 4.6
AsyncLocal<T>
)。
ContinueAwait
完全并创建一个自定义等待器,例如像这样
ContinueOnScope
.这将允许精确控制要继续的线程/上下文以及要流动的状态。
关于c# - 顶级请求上的 ConfigureAwait(false),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31225972/
class test { public static void main(String[] args){ Object o1 = new Object(); O
我以为我理解了 Python 中的这两个单例值,直到我看到有人在代码中使用 return l1 or l2,其中 l1 和 l2 都是链表对象,并且(s)他想如果不为 None 则返回 l1,否则返回
这个问题在这里已经有了答案: Why does the expression 0 >> (True == False) is False True >>> True == (False is Fals
为什么在 Python 中它是这样评估的: >>> False is False is False True 但是当用括号尝试时表现如预期: >>> (False is False) is False
我有一个名为“apple”的表,我编写了以下查询: select name, count(name), case when istasty is null then fal
python boolean 逻辑中的运算符优先级 print(False==True or False) #answer is True print(False==(False or True))#
请不要看条件,因为它们在这里是为了便于理解行为 为什么 result 等于 true ? boolean result = false && (false)?false:true; 我知道我们可以通过
乍一看,这篇文章可能看起来像是重复的,但事实并非如此。相信我,我已经查看了所有 Stack Overflow,但都无济于事。 无论如何,我从 Html.CheckBoxFor 得到了一些奇怪的行为。
这个问题在这里已经有了答案: python operator precedence of in and comparison (4 个答案) 关闭 6 年前。 我的一位前辈演示了它,我想知道这是否是
我最近参加了 Java 的入门测试,这个问题让我很困惑。完整的问题是: boolean b1 = true; boolean b2 = false; if (b2 != b1 != b2) S
为什么 {} == false 评估为 false 而 [] == false 评估为 true在 javascript 中? 最佳答案 这是根据 Abstract Equality Comparis
这个问题在这里已经有了答案: Why does (1 in [1,0] == True) evaluate to False? (1 个回答) 关闭7年前。 为什么使用括号时这些语句按预期工作: >>
我试过搜索这个,但我真的不知道如何表达它以查看是否有其他人发布了答案。 但是,我正在制作一个国际象棋游戏和一个人工智能来配合它,这是非常困难的,我的问题是当我检查两个棋子是否在同一个团队时我必须做 (
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
为什么 为 false || null 返回与 null || 不同的结果错误? 我可以安全地依赖 return myVar || false 如果 myVar 为 null 或 false,则返回
我正在尝试遵循 NHibernate 教程,“你的第一个基于 NHibernate 的应用程序:修订 #4”在 NHibernate Forge。 但线路:new SchemaExport(cfg).
这个问题在这里已经有了答案: Empty list boolean value (3 个答案) 关闭 4 年前。 我是 Python 的新手,不理解以下行为: 为什么要声明 [] == False
以下函数循环访问对象的值。如果值为空this.hasInvalidValue设置为true ,如果不为空 this.hasInvalidValue设置为false : user: { email:
所以我正在玩 java.lang.reflect 东西并尝试制作类似 this 的东西。这是我的问题(可能是一个错误): 将字段设置为 true 的方法的代码: private static void
当我在编程时,我的 if 语句出现了意想不到的结果。 这个代码警报怎么会是真的?我在 W3S 没有找到任何可以帮助我的东西,我真的很想知道为什么这些警报是“正确的” window.alert(fals
我是一名优秀的程序员,十分优秀!