You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

并行执行EF映射存储过程遇异常:首次正常二次报错求解决方案

Why You're Getting "The underlying provider failed to open" on Second Execution

First off, the root cause here is that Entity Framework's DbContext is not thread-safe. You're sharing a single myDbContext instance across two parallel tasks, which is a big no-no. DbContexts are designed to be used by one thread at a time—when multiple tasks hit the same instance simultaneously, it messes up internal state like database connections and change tracking. The first run might work by luck, but by the second execution, the DbContext's internal state is corrupted, leading to the connection failure error.

The Optimal Way to Run These Stored Procedures in Parallel

To fix this and get efficient parallel execution, follow these key rules:

  • Use a separate DbContext for each task: DbContexts are lightweight, so creating a new one per task has negligible performance cost. This eliminates all thread-safety issues.
  • Leverage EF's async APIs: Replace synchronous ToList() with ToListAsync() and use Task.WhenAll() instead of Task.WaitAll()—this avoids blocking threads and is more efficient for modern .NET apps.
  • Ditch Task.Factory.StartNew: Task.Run() is the better choice here; it's simpler and behaves more predictably with async code.

Here's the revised code:

// Spawn two parallel tasks, each with its own DbContext
var userItemsTask = Task.Run(async () => 
{
    using(var ctx = new myDbContext()) 
    {
        return await ctx.zsp_select_UserItems(UserId).ToListAsync();
    }
});

var transactionsTask = Task.Run(async () => 
{
    using(var ctx = new myDbContext()) 
    {
        return await ctx.zsp_select_Transactions(UserId, intoPast, LastUpdatedAt).ToListAsync();
    }
});

// Wait for both tasks to complete and retrieve results
var completedTasks = await Task.WhenAll(userItemsTask, transactionsTask);
var items = completedTasks[0];
var result = completedTasks[1];

Bonus Tips

  • Don't worry about database connection pool pressure—connection pooling is handled automatically by ADO.NET, and the default settings work well for most scenarios.
  • Never share a DbContext across threads. This is a fundamental EF best practice that prevents a whole host of hard-to-debug issues.
  • Using async methods will boost your app's throughput, especially in web or high-concurrency scenarios, by freeing up threads to handle other requests while waiting for database calls to finish.

内容的提问来源于stack exchange,提问作者User987

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:33:58