DataAdapter Fill Async Exception
У меня есть набор асинхронных методов, которые я написал для быстрой обработки большого количества операций извлечения и компиляции базы данных. По большей части они работают фантастически и действительно творили чудеса для моего программного обеспечения. Однако недавно у меня возникла небольшая проблема с методами: время от времени пользователь ошибается, и временные рамки, в которые программное обеспечение извлекает данные, становятся огромными, а время ожидания адаптера данных до получения информации. Обычно в методе синхронизации вы используете try / catch для решения таких проблем, но я пробовал это безрезультатно. Есть ли способ асинхронной обработки исключений, просто бросить, как метод синхронизации, чтобы мой catch / try все try / catch мог работать правильно?
Это пример использования асинхронного метода адаптера данных:
private async Task<DataTable> WWQuery2Run
(string A, string B, string C, string D)
{
using ( var conn = new System.Data.SqlClient.SqlConnection(ReportResources.ConnString) )
{
var temp = new DataTable();
var DA = new SqlDataAdapter(string.Format(ReportResources.Instance.CureInfoQueries["WWQuery2"], A, B, C, D), conn);
await Task.Run(() => DA.Fill(temp));
return temp;
}
}
РЕДАКТИРОВАТЬ:
После всех проблем, связанных с попытками обработать исключения из тайм-аута, я понял, что это не очень хорошая практика. Я пошел дальше и добавил метод для вычисления длительности перед тем, как войти в показанный асинхронный метод и предупредить пользователя о длине, и дал им возможность прервать компиляцию. Имея это в виду, я увеличил время ожидания запроса до суммы, которая должна охватывать все, кроме худшего из худших сценариев, если пользователь желает продолжить. Я также добавил к описанию элементов в программе расчетную продолжительность, чтобы они знали, что прошло много времени, прежде чем пытаться выполнить запрос и компиляцию.
Спасибо @Murad Garibzada за вашу помощь.
3 ответа
Наряду с увеличением времени ожидания команды вы можете использовать блок try / catch. Поскольку вы ожидаете, управление не вернется к вашему телефонному коду до WWQuery2Run
завершено. Если WWQuery2Run
Выдает SomeException, он будет перехвачен и обработан кодом.
private async Task<DataTable> WWQuery2Run(string A, string B, string C, string D)
{
try
{
using ( var conn = new System.Data.SqlClient.SqlConnection(ReportResources.ConnString) )
{
var temp = new DataTable();
var DA = new SqlDataAdapter(string.Format(ReportResources.Instance.CureInfoQueries["WWQuery2"], A, B, C, D), conn);
await Task.Run(() => DA.Fill(temp));
return temp;
}
}
catch (SomeException ex)
{
// handle exception
}
}
Потому что твоя связь
conn
завернут в
using
заявление, есть вероятность, что он будет удален до вашего обращения в
Fill
выполняется.
Вероятно, сработает что-то вроде следующего:
private async Task<DataTable> WWQuery2Run (string A, string B, string C, string D)
{
var temp = new DataTable();
await Task.Run(() => {
using ( var conn = new System.Data.SqlClient.SqlConnection(ReportResources.ConnString) )
{
var DA = new SqlDataAdapter(string.Format(ReportResources.Instance.CureInfoQueries["WWQuery2"], A, B, C, D), conn);
DA.Fill(temp)
}
});
return temp;
}
Вы можете увеличить время ожидания команды адаптера, как показано ниже:
SqlDataAdapter adapter= new SqlDataAdapter(strSQLString, conUS);
adapter.SelectCommand.CommandTimeout=120;
Обработка исключений:
private async Task<DataTable> WWQuery2Run
(string A, string B, string C, string D)
{
using ( var conn = new System.Data.SqlClient.SqlConnection(ReportResources.ConnString) )
{
var temp = new DataTable();
var DA = new SqlDataAdapter(string.Format(ReportResources.Instance.CureInfoQueries["WWQuery2"], A, B, C, D), conn);
Task task = new Task(() => DA.Fill(temp));
try
{
task.Wait();
}
catch (Exception ae)
{
}
return temp;
}
}