Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步填充数据集_C#_Multithreading_Ado.net_Dataset_Thread Safety - Fatal编程技术网

C# 异步填充数据集

C# 异步填充数据集,c#,multithreading,ado.net,dataset,thread-safety,C#,Multithreading,Ado.net,Dataset,Thread Safety,下面的方法用于填充数据集 如果我们以同步方式调用这个方法,它就可以正常工作 但现在我们需要以异步方式调用这个方法。所以我需要做些什么更改,以使下面的方法能够正常工作,而不会出现任何问题 public DataSet Filldata(string ProcName, string TableName) { DataSet ds = new DataSet(); try { da = new SqlDataAdapter(ProcName, con);

下面的方法用于填充数据集

如果我们以同步方式调用这个方法,它就可以正常工作

但现在我们需要以异步方式调用这个方法。所以我需要做些什么更改,以使下面的方法能够正常工作,而不会出现任何问题

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);
            }
}

您可以如下所示声明类级静态对象

private static object lockObject = new object();
并修改您的方法如下,因为Fill方法负责连接的打开和关闭,所以我们可以在它之前添加lock语句

 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() {
      ..... 
   } 
公共异步任务GetDataSetAsync(){ ..... } 因此,最终结果如下所示:

public async Task<DataSet> GetDataSetAsync() {

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

return ds;
} 
公共异步任务GetDataSetAsync(){ DataSet ds=wait Task.Run(()=>FillData(spName,tableName)); 返回ds; } 那是包装纸,它只给你一个想法。不过,你可能不应该这样做。我将把Task.Run放在调用SqlDataAdapter.Fill的最低级别


这在.NetFrameWork WebAPI中不起作用,但在.Net Core WebAPI和Core或常规.Net控制台程序中起作用,只要您参考NuGet Package System.Data.SqlClient 4.6.0。在.Net Framework WebAPI(非核心)中,由于进程在WAIT语句中消失,WAIT似乎在另一个线程中返回数据集。

没有异步API<代码>数据集日期之前的异步长边距,设计用于同步加载;它需要更改DataTable.Load[Async]的内部。要使其工作,目前正在努力实现DataAdapter的异步功能。请在Hello Deepak处填写.NET,感谢您的帮助。Wait关键字在.net Framework 4.0中不可用,我们正在使用.net Framework 4.0。如果可能,您可以尝试从Nuget安装Microsoft.Bcl.Async软件包,以解决.net Framework 4.0中的上述问题。这允许在.Net 4.0中使用async/await。我已经安装了上述软件包。hello Deepak您可以帮助我而不是await吗?我们可以使用锁定,以便只有一个线程可以在FillDataAsync方法中移动。如果是,请帮助我如何在FillDataAsync方法上使用锁定。因为有时我在FillDataAsync中会遇到这种错误方法“已经有一个与此命令关联的打开的DataReader,必须先关闭它。”
public async Task<DataSet> GetDataSetAsync() {

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

return ds;
}