- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我最近写了下面的代码:
Task<T> ExecAsync<T>( string connectionString, SqlCommand cmd, Func<SqlCommand, T> resultBuilder, CancellationToken cancellationToken = default(CancellationToken) )
{
var tcs = new TaskCompletionSource<T>();
SqlConnectionProvider p;
try
{
p = GetProvider( connectionString );
Task<IDisposable> openTask = p.AcquireConnectionAsync( cmd, cancellationToken );
openTask
.ContinueWith( open =>
{
if( open.IsFaulted ) tcs.SetException( open.Exception.InnerExceptions );
else if( open.IsCanceled ) tcs.SetCanceled();
else
{
var execTask = cmd.ExecuteNonQueryAsync( cancellationToken );
execTask.ContinueWith( exec =>
{
if( exec.IsFaulted ) tcs.SetException( exec.Exception.InnerExceptions );
else if( exec.IsCanceled ) tcs.SetCanceled();
else
{
try
{
tcs.SetResult( resultBuilder( cmd ) );
}
catch( Exception exc ) { tcs.TrySetException( exc ); }
}
}, TaskContinuationOptions.ExecuteSynchronously );
}
} )
.ContinueWith( _ =>
{
if( !openTask.IsFaulted ) openTask.Result.Dispose();
}, TaskContinuationOptions.ExecuteSynchronously );
}
catch( Exception ex )
{
tcs.SetException( ex );
}
return tcs.Task;
}
这按预期工作。使用 async/await 编写的相同代码(显然)更简单:
async Task<T> ExecAsync<T>( string connectionString, SqlCommand cmd, Func<SqlCommand, T> resultBuilder, CancellationToken cancellationToken = default(CancellationToken) )
{
SqlConnectionProvider p = GetProvider( connectionString );
using( IDisposable openTask = await p.AcquireConnectionAsync( cmd, cancellationToken ) )
{
await cmd.ExecuteNonQueryAsync( cancellationToken );
return resultBuilder( cmd );
}
}
我快速查看了 2 个版本生成的 IL:async/await 更大(不足为奇)但我想知道 async/await 代码生成器是否分析了一个延续实际上是同步使用的事实TaskContinuationOptions.ExecuteSynchronously
它可以...我在 IL 生成的代码中找不到它。
如果有人知道或对此有任何线索,我很乐意知道!
最佳答案
I was wondering if the async/await code generator analyses the fact that a continuation is actually synchronous to use
TaskContinuationOptions.ExecuteSynchronously
where it can... and I failed to find this in the IL generated code.
await
continuations - without ConfigureAwait(continueOnCapturedContext: false
) - 异步或同步执行取决于同步上下文的存在当它到达 await
点时正在执行您的代码的线程。如果 SynchronizationContext.Current != null
,则进一步的行为取决于 SynchronizationContext.Post
的实现。
例如,如果您在 WPF/WinForms 应用程序的主 UI 线程上,您的延续将在同一线程上执行,但仍然异步,在消息循环的 future 迭代中。它将通过 SynchronizationContext.Post
发布。前提是先行任务已在线程池线程或不同的同步上下文(例如 Why a unique synchronization context for each Dispatcher.BeginInvoke callback?)上完成。
如果前面的任务已在具有相同同步上下文的线程(例如 WinForm UI 线程)上完成,await
延续将同步(内联)执行。 SynchronizationContext.Post
将不会在这种情况下使用。
在没有同步上下文的情况下,await
延续将在先前任务已完成的同一线程上同步执行。
这就是它与使用 TaskContinuationOptions.ExecuteSynchronously
实现的 ContinueWith
的不同之处,它根本不关心初始线程或完成线程的同步上下文,并始终同步执行延续(尽管如此,仍有 exceptions to this behavior)。
您可以使用 ConfigureAwait(continueOnCapturedContext: false)
来更接近所需的行为,但它的语义仍然不同于 TaskContinuationOptions.ExecuteSynchronously
。事实上,它指示调度程序不在具有任何同步上下文的线程上运行延续,因此您可能会遇到 ConfigureAwait(false)
pushes the continuation to thread pool 的情况,而您可能一直期待同步执行。
还相关:Revisiting Task.ConfigureAwait(continueOnCapturedContext: false)
.
关于c# - 异步/等待与手工制作的延续 : is ExecuteSynchronously cleverly used?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30919601/
我可能是个白痴,但我还没能弄清楚这个问题。我正在尝试使用数据库为简单的 CRUD 框架设置一些类。 我从 Entity开始 界面和 Users implements Entity 类。 然后作为“da
背景:最近在查看“结构化文本编辑器”时,我注意到他们使用了一个技巧来更改 python/perl/c++/java 等。通过将 XML 潜入相应语言的注释中,将其转化为“结构化”大纲。 我记得我也曾经
此组件的渲染方法确实使用提供给组件的任何 Prop 。 组件是否会在 props 发生变化时重新渲染? class MyComponent extends React.Component { co
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 9 年前。 Improve this qu
我经常运行 git commit --only --amend 改写我最近一次提交的提交消息。无论我的工作目录是否干净,这都会起作用。 今天我注意到,在执行此操作时,我的 core.editor 中显
我正在尝试制定一个问题,以便只有重写就足够了 来证明目标。我想避免“聪明”地使用命题,而是使用 可以由 Coq 计算的 bool 值。 我定义了一个 bool 测试函数 member如果元素在列表中,
处理数学问题时,我非常喜欢 LINQ to Data。 我想知道当我使用的 IEnumerable 已经是一个数组时,LINQ 是否足够聪明,可以避免像 .ToArray() 这样的转换。请参见下面的
我最近写了下面的代码: Task ExecAsync( string connectionString, SqlCommand cmd, Func resultBuilder, Cancell
诚然,标题可能有点令人困惑,所以我将从一个例子开始。 我有一个包含大量数据的表。我将日期传递给存储过程,该存储过程将用作非常标准的 select 上的 where 的一部分: @MinDate DAT
前段时间发现了一个类似Clever CSS的CSS框架,但是我不记得它的名字了,现在找不到了。 你知道像 Clever CSS 这样的 CSS 框架吗?它就像 Clever CSS,但更强大。 谢谢。
我不知道这是聪明还是愚蠢。我喜欢 CL-WHO,也喜欢 Python,所以我一直在想办法将两者结合起来。我想说的是: tag("html", lst( tag("head"),
我已经创建了几个使用 Core Data 的应用程序并进行了大量实验,但我从未找到实现简单添加/编辑 viewController 的“完美”方法。我只想实现一个能够管理编辑和添加功能的 Contro
我有两列的行:产品 SKU 和类别 ID我只需要返回与 cat_ids 列表匹配的产品 SKU 和它们的 cat_ids在 SQL 中是: SELECT SKU,cat_id FROM myTable
这是导致问题的简单代码: class CoreViewController: UIViewController { private let isPad = UI_USER_INTERFACE_
完整的错误是“IR 生成失败:程序太聪明:变量与现有符号 _TWPSaSs12SequenceType 发生冲突”。 我正在编写一堆函数作为学习 Swift 的练习,尤其是 Swift 泛型。我的最新
未知:0:错误:IR 生成失败:程序太聪明:变量与现有符号 OBJC_CLASS_$_UIDevice 冲突 这是 Xcode 7.0.1 抛出的错误信息。我不知道,我做错了什么让 Xcode 抛出这
我是一名优秀的程序员,十分优秀!