Async methods with or without ConfigureAwait on NetStandard lib for Net Core

耗尽温柔 提交于 2019-12-23 04:36:35

问题


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

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

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

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 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?


回答1:


In this situation is it better to use 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:

  • 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.

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.

On a side note, try out the boolean argument hack to prevent code duplication in your synchronous/asynchronous method pairs.

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

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?



来源:https://stackoverflow.com/questions/45631840/async-methods-with-or-without-configureawait-on-netstandard-lib-for-net-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!