我正在开发一个实用程序,它将使用 ExecuteNonQueryAsync 并行执行多个 SqlCommand。该实用程序仅应在所有请求完成后返回,因此我使用的是 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 调用中添加一个秒表参数,然后将手表数组传递给 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);
}
我可以在 executeSQL 函数中调用 ExecuteNonQueryAsync 之前启动秒表。但是我什么时候可以阻止它?
这就是我试图解决问题的方式。我想我会添加一个延续来停止秒表,然后等待延续。但是此代码无效(无法将类型 '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) {
// ...