Net Core的NetStandard lib上具有或不具有ConfigureAwait的异步方法 [英] Async methods with or without ConfigureAwait on NetStandard lib for Net Core

查看:279
本文介绍了Net Core的NetStandard lib上具有或不具有ConfigureAwait的异步方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个正在批量插入的库.
库是.NetStandard(1.4)中的EfCore扩展,因此可以在针对.NetCore(1.0+)或完整NetFramework(4.6.1+)的ASP.NET Core项目中使用. 功能之一是:

I have a library that is doing bulk insert.
Library is EfCore extension made in .NetStandard(1.4) so it can be used in ASP.NET Core projects targeting both .NetCore(1.0+) or full NetFramework(4.6.1+)
One of the functions is:

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);
        ....
    }
}

接下来,我添加了具有 async 支持

Next I have added the same method with async support

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);
        ....
    }
}

现在建议我更改异步方法,以将 ConfigureAwait(false)添加到内部方法中,并通过删除显式<像这样的公开方法中的em> async 关键字:

And now I was advised to change the async method in a way to add ConfigureAwait(false) to internal method and also to optimize out simple async by removing explicit async keyword from exposed method like this:

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);
    }
}

问题是:
在这种情况下,最好使用 ConfigureAwait(false)?
其次是在示例示例中从暴露的方法中删除 async 关键字吗?

So the question being:
In this situation is it better to use ConfigureAwait(false)?
And secondly is removing async keyword from exposed methods for scenario in example advisable?

PS我已经读了一些博客和关于这些问题的几个问题,但仍未得出确切的答案. 我读到ASP.NET Core不再有上下文",因此考虑到这里的最佳做法是什么?

PS I have already read few blogs and several questions here regarding these issue but still haven't come to conclusive answer. I read that ASP.NET Core no longer has a "context" so taking that into the consideration what would be the best practice here?

推荐答案

在这种情况下,最好使用ConfigureAwait(false)吗?

In this situation is it better to use ConfigureAwait(false)?

我通常建议使用ConfigureAwait(false)作为库代码. 将近十年前的相同建议今天仍然适用.但是,这里有一些缓解因素:

I generally recommend ConfigureAwait(false) for library code. The same advice from nearly half a decade ago still applies today. However, there are some mitigating factors here:

  • 个目标平台不提供SynchronizationContext.因此,只要您的代码仅在这些平台上运行,就不需要ConfigureAwait(false).
  • ASP.NET Core和 EF核心团队不再使用 .但是,请注意,EF核心团队确实提供了同步API,因此人们首先想到的是人们不会阻塞他们的异步代码,所以缺少ConfigureAwait(false)不会'在带有SynchronizationContext的平台上使用时,不会导致死锁.
  • Your only target platforms do not provide a SynchronizationContext. Thus, as long as your code only runs on those platforms, ConfigureAwait(false) isn't necessary.
  • Both the ASP.NET Core and EF Core teams no longer use ConfigureAwait(false). However, note that the EF Core team does provide synchronous APIs, so the idea there is that people won't be blocking on their asynchronous code in the first place, so a lack of ConfigureAwait(false) won't cause a deadlock when used on platforms with a SynchronizationContext.

因此,在您的情况下,可以选择 not 来包含ConfigureAwait(false).我想说这是一种有效的方法,因为您的库是EFCore的扩展,并且您正在提供同步和异步API(就像EFCore一样).请记住,在用户使用SynchronizationContext安装到平台(例如经典ASP.NET)并在您的异步代码上进行阻止的情况下,这会打开死锁.但是EFCore具有相同的局限性.

So, in your case, you can choose not to include ConfigureAwait(false). I'd say that's a valid approach, since your library is an extension to EFCore and since you are supplying synchronous as well as asynchronous APIs (like EFCore does). Do bear in mind that this opens up deadlocks in the scenario where a user installs onto a platform with a SynchronizationContext (e.g., classic ASP.NET) and blocks on your asynchronous code. But EFCore has the same limitation.

另一方面,请尝试布尔参数hack以防止代码重复在您的同步/异步方法对中.

第二,建议在示例中从暴露的方法中删除async关键字吗?

And secondly is removing async keyword from exposed methods for scenario in example advisable?

不.我不确定为什么会建议这样做.这样可以防止最终用户检测到您是否使用了async关键字(编译器在async方法上放置了一个属性),但是谁在乎呢?

No. I'm not sure why this would be recommended. It prevents end-users from detecting whether you're using the async keyword (there's an attribute the compiler places on async methods), but who cares?

这篇关于Net Core的NetStandard lib上具有或不具有ConfigureAwait的异步方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆