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