Asynchronous 在NetCore的NetStandard库上使用或不使用ConfigureAwait的异步方法
我有一个正在进行批量插入的库。Asynchronous 在NetCore的NetStandard库上使用或不使用ConfigureAwait的异步方法,asynchronous,asp.net-core,async-await,configureawait,Asynchronous,Asp.net Core,Async Await,Configureawait,我有一个正在进行批量插入的库。 库是在.NetStandard(1.4)中进行的EfCore扩展,因此它可以用于针对.NetCore(1.0+)或完整NetFramework(4.6.1+)的ASP.NET核心项目 其中一项功能是: public static BulkInsert<T>(this DbContext context, IList<T> entities) { SqlBulkOperation.InsertAsync<T>(contex
库是在.NetStandard(1.4)中进行的EfCore扩展,因此它可以用于针对.NetCore(1.0+)或完整NetFramework(4.6.1+)的ASP.NET核心项目
其中一项功能是:
public static BulkInsert<T>(this DbContext context, IList<T> entities)
{
SqlBulkOperation.InsertAsync<T>(context, entities);
}
internal static class SqlBulkOperation
{
public static void Insert<T>(DbContext context, IList<T> entities)
{
....
sqlBulkCopy.WriteToServer(reader);
....
}
}
publicstaticbulkinsert(此DbContext上下文,IList实体)
{
InsertAsync(上下文、实体);
}
内部静态类操作
{
公共静态void插入(DbContext上下文,IList实体)
{
....
sqlBulkCopy.WriteToServer(读卡器);
....
}
}
接下来,我添加了支持async的相同方法
public static async Task BulkInsertAsync<T>(this DbContext context, IList<T> entities)
{
await SqlBulkOperation.InsertAsync<T>(context, entities, null, null);
}
internal static class SqlBulkOperation
{
public static async Task InsertAsync<T>(DbContext context, IList<T> entities)
{
....
await sqlBulkCopy.WriteToServer(reader);
....
}
}
公共静态异步任务BulkInsertAsync(此DbContext上下文,IList实体)
{
等待SqlBulkOperation.InsertAsync(上下文、实体、null、null);
}
内部静态类操作
{
公共静态异步任务InsertAsync(DbContext上下文,IList实体)
{
....
等待sqlBulkCopy.WriteToServer(读卡器);
....
}
}
现在,有人建议我更改async方法,将ConfigureAwait(false)添加到内部方法中,并通过从公开方法中删除显式async关键字来优化简单async,如下所示:
public static Task BulkInsertAsync<T>(this DbContext context, IList<T> entities)
{
return SqlBulkOperation.InsertAsync<T>(context, entities, null, null, true);
}
internal static class SqlBulkOperation
{
public static async Task InsertAsync<T>(DbContext context, IList<T> entities)
{
await sqlBulkCopy.WriteToServerAsync(reader).ConfigureAwait(false);
}
}
公共静态任务BulkInsertAsync(此DbContext上下文,IList实体)
{
返回SqlBulkOperation.InsertAsync(上下文、实体、null、null、true);
}
内部静态类操作
{
公共静态异步任务InsertAsync(DbContext上下文,IList实体)
{
等待sqlBulkCopy.WriteToServerAsync(读卡器).ConfigureWait(false);
}
}
所以问题是:在这种情况下,是否最好使用ConfigureWait(false)?
第二,从示例中场景的公开方法中删除async关键字是否可取 PS我已经读了一些博客和一些关于这些问题的问题,但仍然没有得出结论性的答案。 我读到ASP.NET核心不再有“上下文”,因此考虑到这一点,这里的最佳实践是什么 在这种情况下,使用ConfigureWait(false)是否更好 对于库代码,我通常建议使用
ConfigureAwait(false)
。然而,这里有一些缓解因素:
- 您唯一的目标平台不提供同步上下文。因此,只要代码只在这些平台上运行,
就没有必要了ConfigureAwait(false)
- ASP.NET核心和。但是,请注意,EF核心团队确实提供了同步API,因此其想法是人们不会首先阻塞异步代码,因此在具有
的平台上使用时,缺少SynchronizationContext
不会导致死锁ConfigureAwait(false)
ConfigureAwait(false)
。我认为这是一种有效的方法,因为您的库是EFCore的扩展,而且您提供的是同步和异步api(就像EFCore一样)。请记住,当用户安装到带有SynchronizationContext
(例如,经典ASP.NET)的平台上并在异步代码上阻塞时,这会打开死锁。但EFCore也有同样的局限性
在旁注上,尝试一下
第二,从示例中场景的公开方法中删除async关键字是否可取
不,我不知道为什么会推荐这个。它阻止最终用户检测您是否正在使用async
关键字(编译器在async
方法上放置了一个属性),但谁在乎呢
在这种情况下,使用ConfigureWait(false)是否更好
对于库代码,我通常建议使用ConfigureAwait(false)
。然而,这里有一些缓解因素:
- 您唯一的目标平台不提供同步上下文。因此,只要代码只在这些平台上运行,
就没有必要了ConfigureAwait(false)
- ASP.NET核心和。但是,请注意,EF核心团队确实提供了同步API,因此其想法是人们不会首先阻塞异步代码,因此在具有
的平台上使用时,缺少SynchronizationContext
不会导致死锁ConfigureAwait(false)
ConfigureAwait(false)
。我认为这是一种有效的方法,因为您的库是EFCore的扩展,而且您提供的是同步和异步api(就像EFCore一样)。请记住,当用户安装到带有SynchronizationContext
(例如,经典ASP.NET)的平台上并在异步代码上阻塞时,这会打开死锁。但EFCore也有同样的局限性
在旁注上,尝试一下
第二,从示例中场景的公开方法中删除async关键字是否可取
不,我不知道为什么会推荐这个。它阻止最终用户检测您是否使用了
async
关键字(编译器在async
方法上放置了一个属性),但谁在乎呢?这已经被问了100次了,答案总是一样的:在类库中总是使用。ConfigureAwait(false)
,在WPF/Console/ASP.NET/ASP.NET核心项目中,永远不要使用它,第二个问题呢,删除async?@borisdj只有在需要继续时才使用wait,否则只返回任务。换句话说,如果调用任务后不需要任务的结果,则无需等待。只需返回任务。BulkInsertAsync
中的async不是必需的,因此它可以正常工作。也没有.configurewait
必要,因为您正在通过