多线程中SqlDataAdapter.Fill失败失败

时间:2017-08-24 12:14:35

标签: c# multithreading thread-safety sqldataadapter

有人可以解释一下为什么SqlDataAdapter.Fill在多线程中失败了吗?我在LinqPad中准备了一个例子:

var connectionString = "Data Source=<server>;Initial Catalog=<DB>;Integrated Security=True";
var connection = new SqlConnection(connectionString);
connection.Open();

var lck = new object();
var tasks = new List<Task>();
for(var i=0; i<64; i++)
tasks.Add(Task.Factory.StartNew(() => 
{
    using(var command = new SqlCommand(string.Format("select {0}", i), connection))
    using(var ds = new DataSet())
    using(var da = new SqlDataAdapter(command))
    {
        //lock(lck)
        {
            da.Fill(ds);
        }
    }
    Console.Write("Ok ");
}));
Task.WaitAll(tasks.ToArray());

它总是给我不同的错误。有时只是挂起。 enter image description here

但如果您取消注释已注释的锁定语句 - 一切都会正常工作。

1 个答案:

答案 0 :(得分:0)

您的任务共享SqlConnection。当任务同时运行时,每个任务都会打开一个数据读取器(使用SqlDataAdapter)。发生异常是因为不允许这样做。只能打开一个数据阅读器。

据我所知,有两种方法可以解决它:

  1. 在每项任务中打开一个新连接。
  2. 激活MARS,即将MultipleActiveResultSets=true添加到您的连接字符串。