Dapper 在 Worker Service 中需手动管理连接生命周期,推荐使用 Transient 注册或方法内 using 创建连接并显式 Open/Close。

Dapper 在 .NET 后台服务(Worker Service)中使用,和在 Web API 或控制台应用里基本一致,核心是连接管理、依赖注入、生命周期适配三点。Worker Service 没有 HTTP 请求上下文,所以不能依赖 `Scoped` 生命周期来自动释放连接,得自己把控。
确保项目包含以下包:
Microsoft.Data.SqlClient,MySQL 用 MySqlConnector,PostgreSQL 用 Npgsql
Microsoft.Extensions.Configuration.Json、Microsoft.Extensions.DependencyInjection
在 Program.cs 中读取 appsettings.json 并注册连接工厂(推荐封装为单例或 transient):
var builder = Host.CreateApplicationBuilder(args);
builder.Configuration.AddJsonFile("appsettings.json");
<p>builder.Services.AddSingleton<IDbConnection>(sp =>
{
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
return new SqlConnection(connectionString); // 或 MySqlConnection/NpgsqlConnection
});
// 或更推荐:注册一个工厂方法,每次调用新建连接(避免跨线程复用)
builder.Services.AddTransient<IDbConnection>(sp =>
{
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
var conn = new SqlConnection(connectionString);
conn.Open(); // Worker 中常需立即打开,避免 Execute 时才 Open 导致异常
return conn;
});通过构造函数注入 IDbConnection(注意:若注册为 Transient,每次注入都是新实例;若为 Singleton,务必手动管理 Open/Close,否则会出错):
public class DataSyncWorker : BackgroundService
{
private readonly IDbConnection _connection;
private readonly ILogger<DataSyncWorker> _logger;
<pre class="brush:php;toolbar:false;">public DataSyncWorker(IDbConnection connection, ILogger<DataSyncWorker> logger)
{
_connection = connection;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
// ✅ 安全写法:确保连接已打开(尤其注册为 Transient 时)
if (_connection.State != ConnectionState.Open)
_connection.Open();
var count = await _connection.QuerySingleAsync<int>(
"SELECT COUNT(*) FROM Orders WHERE Status = @Status",
new { Status = "Pending" });
_logger.LogInformation("待处理订单数: {Count}", count);
// 执行更新等操作...
await _connection.ExecuteAsync(
"UPDATE Orders SET Status = 'Processed' WHERE Status = @Status",
new { Status = "Pending" });
}
catch (Exception ex)
{
_logger.LogError(ex, "数据同步失败");
}
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
}
}}
⚠️ 注意:不要把连接设为 Singleton 并长期保持 Open 状态,容易引发连接池耗尽或超时断连。建议用 Transient + 每次操作前检查 Open 状态,或改用 using 块(见下条)。
直接在方法内创建并释放连接,完全规避生命周期争议:
private async Task ProcessOrdersAsync(CancellationToken ct)
{
var connectionString = _configuration.GetConnectionString("DefaultConnection");
using var conn = new SqlConnection(connectionString);
await conn.OpenAsync(ct);
<pre class="brush:php;toolbar:false;">var orders = await conn.QueryAsync<Order>(
"SELECT * FROM Orders WHERE CreatedAt > @Since",
new { Since = DateTime.UtcNow.AddHours(-1) });
foreach (var order in orders)
{
await conn.ExecuteAsync(
"UPDATE Orders SET Status = 'Handled' WHERE Id = @Id",
new { order.Id });
}}
这种写法清晰、安全、符合 Dapper 原生习惯,也适配 Worker 的长周期运行场景。
基本上就这些。不复杂但容易忽略的是连接状态管理和释放时机——Worker 不像 Web 请求有天然作用域,得自己兜底。
以上就是Dapper怎么在后台服务(Worker Service)中使用 Dapper集成Worker Service的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号