Заполнить набор данных Async - PullRequest
0 голосов
/ 07 мая 2018

Приведенный ниже метод используется для заполнения набора данных.

если мы вызываем этот метод синхронно, он работает нормально.

Но теперь нам нужно вызывать этот метод асинхронно. Итак, какие изменения мне нужно сделать, чтобы приведенный ниже метод работал правильно, без каких-либо проблем.

public DataSet Filldata (строка ProcName, строка TableName) { DataSet ds = new DataSet (); пытаться { da = новый SqlDataAdapter (ProcName, con); if (con.State! = ConnectionState.Open) { con.Open (); } da.SelectCommand.CommandTimeout = 15000; da.Fill (ds, TableName); } поймать (исключение ex) { ErrorMsg = ex.Message.ToString (); HMISLogger.logger.Error (ex.Message.ToString () + "" + ProcName, ex); } в конце концов { con.Close (); da.Dispose (); } возврат дс; }

Ответы [ 3 ]

0 голосов
/ 08 мая 2018

Вы можете объявить статический объект уровня класса, как показано ниже

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;
        }
0 голосов
/ 08 мая 2019

Вы можете сделать это:

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 Console, если вы ссылаетесь на NuGet Package System.Data.SqlClient 4.6.0. Похоже, что в .Net Framework WebAPI (не Core) await возвращает DataSet в другом потоке, потому что процесс исчез в операторе await.

0 голосов
/ 07 мая 2018

Вы можете использовать что-то, как показано ниже, возвращая Task, который является асинхронной операцией

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