将EF DatabaseContext注入自定义ScopedService

时间:2018-05-16 19:34:11

标签: c# asp.net-core-2.0 ef-core-2.0

在我看来,在范围内的服务中注入EF的性能非常低。

在这种情况下,我很有可能错误地使用EF,但在这种情况下,我无法找到正确的说明/文档如何使用EF(将其注入自定义托管服务)。

在EasyRabbit / startup.cs(ConfigureServices)中注册了以下服务:

// db
services.AddDbContext<ApplicationDbContext>(options =>
{
    options.UseSqlServer("Server=localhost; Database=RabbitTest; MultipleActiveResultSets=true; User ID=sa; Password=Admin1234");
});

// default REST Api
services.AddMvc();
// Configuration for Rabbit connector
services.Configure<RabbitConfig>(Configuration.GetSection("RabbitConfig"));
// Rabbit Connector
services.AddSingleton<RabbitConnector>();
// Subscriber which listens if some new message arrives
services.AddSingleton<IHostedService, GenericHostedSubscriber<CalculatorInputs>>();

// Every arival message is then processed in following scope
// ApplicationDbContext dbContext is injected into this RabbitSubscribers.Adder
services.AddScoped<IScopedProcessingService<CalculatorInputs>, RabbitSubscribers.Adder>();

现在,如果我理解正确,它应该为每个新的RabbitSubscribers.Adder范围自动创建db上下文范围。

问题是,像这样它平均每秒只能消耗/处理大约50条消息。

当我从下面的代码中用db(AddAsync和SaveChangesAsync)评论所有操作时,它可以处理大约每秒2000条消息,这很好但没有db对我没用:(

namespace EasyRabbit.RabbitSubscribers
{
    public class Adder : IScopedProcessingService<CalculatorInputs>
    {
        private ILogger<Adder> _logger;
        private ApplicationDbContext _db;

        public Adder(ApplicationDbContext dbContext, ILogger<Adder> logger)
        {
            _logger = logger;
            _db = dbContext;

        }

        public async Task HandleMessageAsync(CalculatorInputs message)
        {

            Console.WriteLine($"Calculator: [{message.FirstNumber}] + [{message.SecondNumber}] = {message.FirstNumber + message.SecondNumber}");
            await _db.Calculations.AddAsync(new Calculation()
            {
                FirstNumber = message.FirstNumber,
                SecondNumber = message.SecondNumber,
                Result = message.FirstNumber + message.SecondNumber
            });

            await _db.SaveChangesAsync();

        }
    }
}

当我尝试用System.Data.SqlClient(在Adder.cs中直接使用的代码片段)替换EF时,它平均每秒处理1100条消息。但与这样的DB合作真的不方便: - /

public static class DB
{
    private static string _connectionString = "Server=localhost; Database=RabbitTest; MultipleActiveResultSets=true; User ID=sa; Password=Admin1234";


    public static void AddRecord(MyDBObject myDBObject)
    {
        using (SqlConnection con = new SqlConnection(_connectionString))
        {
            using (SqlCommand cmd = new SqlCommand("insert into test (FirstNumber, SecondNumber, Result) values (@FirstNumber, @SecondNumber, @Result)", con))
            {
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.AddWithValue("@FirstNumber", myDBObject.FirstNumber);
                cmd.Parameters.AddWithValue("@SecondNumber", myDBObject.SecondNumber);
                cmd.Parameters.AddWithValue("@Result", myDBObject.Result);
                con.Open();
                cmd.ExecuteNonQuery();
                con.Close();
            }

        }
    }
}

public class MyDBObject
{
    public int FirstNumber { get; set; }
    public int SecondNumber { get; set; }
    public int Result { get; set; }
}

可以在https://github.com/suchoss/uServiceChasis

上找到整个代码

感谢。

重现的步骤

  1. 从以下网址克隆当前存储库:https://github.com/suchoss/uServiceChasis
  2. https://www.rabbitmq.com/#getstarted
  3. 安装RabbitMQ
  4. 安装MSSQL
  5. 在EasyRabbit / startup.cs(第31行)中将连接器更改为DB
  6. 转到文件夹RandomNumberPairGenerator并运行命令dotnet运行几秒钟,然后你可以用ctrl + c取消它(它会在RabbitMQ队列中创建一些消息)
  7. 运行EasyRabbit项目并观察每秒处理的消息数 *。如果您安装了RabbitMQ管理,您可以在http://localhost:15672上观看性能(默认登录:访客;密码:访客)
  8. 编辑:

    以下是当前测量的表现:

    1. adder.cs中的EF异步 - 230 / s
    2. 在adder.cs内没有异步的EF - 100 / s
    3. ADO.NET async - 1300 / s
    4. 没有异步的ADO.NET - 150 / s
    5. EF注入上下文异步 - 40 / s
    6. 没有异步的EF注入上下文 - 65 / s
    7. 方案1.,2.,3.,4。将adder.cs作为单身人士

      场景5.,6。他们将adder.cs作为范围服务

0 个答案:

没有答案