填充数据集异步

Fill Dataset Async

以下方法用于填充数据集。

如果我们以同步方式调用此方法,它工作正常。

但现在我们需要在异步中调用此方法way.so我需要做哪些更改才能使下面的方法正常工作而不会出现任何问题。

public DataSet Filldata(string ProcName, string TableName)
{
    DataSet ds = new DataSet();
    try
    {
        da = new SqlDataAdapter(ProcName, con);
        if (con.State != ConnectionState.Open)
        {
            con.Open();
        }
        da.SelectCommand.CommandTimeout = 15000;
        da.Fill(ds, TableName);
    }
    catch (Exception ex)
    {
        ErrorMsg = ex.Message.ToString();
        HMISLogger.logger.Error(ex.Message.ToString() + " " + ProcName, ex);
    }
    finally
    {
        con.Close();
        da.Dispose();
    }
    return ds;
}

你可以使用下面的东西,返回异步操作的任务

public Task<DataSet> FilldataAsync(string ProcName, string TableName)
{
    try
            {
                return Task.Run(() =>
                {
                    DataSet ds = new DataSet();
                    using (var da = new SqlDataAdapter(ProcName, con))
                    {
                        da.SelectCommand.CommandTimeout = 15000;
                        da.Fill(ds, TableName);
                        return ds;
                    }
                });
            }
            catch (Exception ex)
            {
                ErrorMsg = ex.Message.ToString();
                HMISLogger.logger.Error(ex.Message.ToString() + " " + ProcName, ex);
            }
}

您可以使用 async/await 关键字来调用它,

private async Task GetSomeData(string sSQL)
{
    DataSet results = await FilldataAsync(ProcName, TableName);
    //Populate once data received
    grdRes.DataSource = results.Tables[0];
}

您可以如下声明class级静态对象

private static object lockObject = new object();

并如下修改你的方法,因为 Fill 方法负责连接的打开和关闭,我们可以在它之前添加锁定语句。

 public DataSet Filldata(string ProcName, string TableName)
        {
            DataSet ds = new DataSet();
            try
            {

                da = new SqlDataAdapter(ProcName, con);
                da.SelectCommand.CommandTimeout = 15000;
                lock (lockObj)
                {
                    da.Fill(ds, TableName);
                }
            }            
            catch (Exception ex) {
                ErrorMsg = ex.Message.ToString();
                HMISLogger.logger.Error(ex.Message.ToString() + " " + ProcName, ex);
            }
            finally {
                con.Close();
                da.Dispose();
            }
            return ds;
        }

你可以这样做:

DataSet ds = await Task.Run(() => FillData(spName, tableName)); 

但语句必须在某个异步函数中,即:

public async Task<DataSet> GetDataSetAsync() {
      ..... 
   } 

所以最终结果看起来像这样:

public async Task<DataSet> GetDataSetAsync() {

DataSet ds = await Task.Run(() => FillData(spName, tableName)); 

return ds;
} 

那是包装器,它只为您提供思路。你可能不应该那样做。我会将 Task.Run 放在调用 SqlDataAdapter .Fill 的最低级别

这在 .NetFrameWork WebAPI 中无效,但在 .Net Core WebAPI 和 Core 或常规 .Net 控制台程序中有效,只要您引用 NuGet 包 System.Data.SqlClient 4.6.0。在 .Net Framework WebAPI(非核心)中,似乎等待 returns DataSet 在不同的线程中,因为进程在 await 语句处消失了。