Я разрабатываю утилиту, которая будет выполнять несколько SqlCommands параллельно, используя ExecuteNonQueryAsync.Утилита должна возвращаться только после завершения всех запросов, поэтому я использую WaitAll.
Как это бывает, эта утилита является хранимой процедурой SQL CLR. Это исключает использование Task.Run () .
Я хочу перехватить все возникающие отдельные исключения, которые, кажется, работают нормально.Сейчас я пытаюсь добавить возможность также получать истекшую длительность каждой отдельной задачи в массиве.
Вот ядро кода без никакой информации о затраченном времени:
// the commands array has been populated with an array of strings (TSQL statemements to execute)
Task<int>[] tasks = new Task<int>[commands.Length];
try {
for (int i = 0; i < commands.Length; i++) {
// executeSQL is an asyc method which makes the appropriate connection and returns await ExecuteNonQueryAsync
tasks[i] = executeSql(commands[i], connectionString, (int)commandTimeout);
}
Task.WaitAll(tasks);
} catch (AggregateException) {
// exceptions reported in GetResults
} finally {
//GetResults builds a datatable of { command, result, exception text }
var results = GetResults(commands, tasks);
}
Теперь я пытаюсь выяснить, как получить истекшее время каждого отдельного запроса ExecuteNonQueryAsync.
Моей первой мыслью было создание массива секундомеров и добавление параметра секундомера ввызов executeSQL, а затем передать массив watches функции GetResults:
Task<int>[] tasks = new Task<int>[commands.Length];
Stopwatch[] watches = new Stopwatch[commands.Length];
try {
for (int i = 0; i < commands.Length; i++) {
tasks[i] = executeSql(commands[i], connectionString, (int)commandTimeout, watches[i]);
}
Task.WaitAll(tasks);
} catch (AggregateException) {
// exceptions reported in finally
} finally {
var results = GetResults(commands, tasks, watches);
}
Я могу запустить секундомер непосредственно перед вызовом ExecuteNonQueryAsync внутри функции executeSQL.Но когда я смогу это остановить?
Это насколько я пытался решить проблему.Я думал, что добавлю продолжение, чтобы остановить секундомер и дождаться продолжения.Но этот код недопустим ( Не удалось неявно преобразовать тип 'System.Runtime.CompilerServices.ConfiguredTaskAwaitable>' в 'System.Threading.Tasks.Task' )
var tasks = new Task<int>[commands.Length];
var watches = new System.Diagnostics.Stopwatch[commands.Length];
try {
for (int i = 0; i < commands.Length; i++) {
tasks[i] = executeSql(commands[i], connectionString, (int)commandTimeout, watches[i]).ContinueWith(
t => {
watches[i].Stop();
return t;
},
TaskContinuationOptions.AttachedToParent
).ConfigureAwait(false);
}
Task.WaitAll(tasks);
} catch (AggregateException) {
// ...