并行执行存储过程

Muf*_*lix 10 c# asp.net-mvc task-parallel-library

我有这两种方法

public DataTable GetData1(int Id)
{
    DataTable dt = new DataTable();

    using (SqlConnection sqlcon = new SqlConnection(database.Connection.ConnectionString))
    {
        using (SqlCommand cmd = new SqlCommand("spGetData1", sqlcon))
        {
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add(new SqlParameter() { ParameterName = "@id", Value = Id});

            using (SqlDataAdapter da = new SqlDataAdapter(cmd))
            {
                da.Fill(dt);
            }
        }
    }

    return dt;
}

public DataTable GetData2(int Id)
{
    DataTable dt = new DataTable();

    using (SqlConnection sqlcon = new SqlConnection(database.Connection.ConnectionString))
    {
        using (SqlCommand cmd = new SqlCommand("spGetData2", sqlcon))
        {
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add(new SqlParameter() { ParameterName = "@id", Value = Id});

            using (SqlDataAdapter da = new SqlDataAdapter(cmd))
            {
                da.Fill(dt);
            }
        }
    }
    return dt;
}
Run Code Online (Sandbox Code Playgroud)

我想立即执行它们并获取数据以便进一步处理.

我试过类似的东西

var task1 = Task.Factory.StartNew(() => database.Data.GetData1(1));
var task2 = Task.Factory.StartNew(() => database.Data.GetData2(2));

var taskList = new List<Task> { task1, task2 };

Task.WaitAll(taskList.ToArray());
Run Code Online (Sandbox Code Playgroud)

但在最后一行它崩溃了

有一个或多个错误

内在的例外是

你调用的对象是空的.

堆栈跟踪

at System.Threading.Tasks.Task.WaitAll(Task [] tasks,Int32 millisecondsTimeout,CancellationToken cancellationToken)

connectionString是从System.Data.Entity.DbContext.Database课堂上获得的

 public class DatabaseRepository : IDisposable
    {
        DbContext dbContext;

        public DatabaseRepository()
        {
             dbContext = new DbContext("connection string ...");
             Data = new DataRepository(dbContext.Database);

        }
        public DataRepository Data { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但错误是相同的,即使我手动设置连接字符串,所以我不认为错误在这里.

   using (SqlConnection sqlcon = new SqlConnection("connection string ..."))
   {
      using (SqlCommand cmd = new SqlCommand("spGetData2", sqlcon))
      {
       ...
      }
   }
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?我看到一些示例使用Async返回类型,但我不想复制这些方法.

Jer*_*son 5

database.Connection.ConnectionString一个静态字符串,否则您无法编译,因为 "非静态字段,方法或属性需要对象引用".

考虑到这一点,它不是因为它的静态而未被解释的连接字符串......即使你故意将静态字符串初始化为Null,那么错误消息将是:

InnerException = {"ConnectionString属性尚未初始化."}

这是一个repro,除非你的GetData方法在空对象中,否则无法生成错误:

namespace database
{
public class Program
{
    static void Main(string[] args)
    {
        //WORKS!!
        var repro = new database.Data();
        var task1 = Task.Factory.StartNew(() => repro.GetData1(3));
        var task2 = Task.Factory.StartNew(() => repro.GetData2(5));
        var taskList = new List<Task> { task1, task2 };
        Task.WaitAll(taskList.ToArray());

        //FAILS WITH ERROR REPORTED!!
        repro = null;
        var task1 = Task.Factory.StartNew(() => repro.GetData1(3));
        var task2 = Task.Factory.StartNew(() => repro.GetData2(5));
        var taskList = new List<Task> { task1, task2 };
        Task.WaitAll(taskList.ToArray());
    }
}

class Data
{
    private string connectionString = "Server=.;Database=CRUD_Sample;Integrated Security=True;Asynchronous Processing = True;";
    public DataTable GetData1(int Id)
    {
        DataTable dt = new DataTable();
        using (SqlConnection sqlcon = new SqlConnection(connectionString))
        {
            using (SqlCommand cmd = new SqlCommand("Get_CustomerbyID", sqlcon))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(new SqlParameter() { ParameterName = "@id", Value = Id });
                using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                {
                    da.Fill(dt);
                }
            }
        }
        return dt;
    }

    public DataTable GetData2(int Id)
    {
        DataTable dt = new DataTable();
        using (SqlConnection sqlcon = new SqlConnection(connectionString))
        {
            using (SqlCommand cmd = new SqlCommand("Get_CustomerbyID", sqlcon))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(new SqlParameter() { ParameterName = "@id", Value = Id });
                using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                {
                    da.Fill(dt);
                }
            }
        }
        return dt;
    }
}
}
Run Code Online (Sandbox Code Playgroud)

调试

你如何找到NullReferenceException的来源?除了查看异常本身之外 - 关键是NRE将被精确地抛出它发生的位置然后将鼠标悬停在代码行上的变量上并查看哪个对象为空.