We have a long-running operation that read millions of records in a loop. I was wondering if I should call ThrowIfCancellationRequested
in that loop (which would mean it is executed N times), or should I do it only every 1000th time?
So my question really is: how expensive is a call to ThrowIfCancellationRequested? Does it involve database reading?
Yes, it does involve database querying, but only one query is being issued:
_cancellationTokenHolder = new Lazy<CancellationTokenHolder>(
() => new CancellationTokenHolder(_shutdownToken),
LazyThreadSafetyMode.None);
if (WatchedServers.TryGetValue(_serverId, out _watchedTokens))
{
_watchedTokens.TryAdd(this, null);
}
}
public void Dispose()
{
lock (_syncRoot)
{
if (_disposed) return;
_disposed = true;
_watchedTokens?.TryRemove(this, out _);
if (_cancellationTokenHolder.IsValueCreated)
{
And some deserialization stuff in SQL Server implementation:
return _storage.UseConnection(_dedicatedConnection, connection => connection
.ExecuteScalar<long>(queryString, queryParameters, commandTimeout: _storage.CommandTimeout)
.ToString(CultureInfo.InvariantCulture));
}
return _storage.UseTransaction(_dedicatedConnection, (connection, transaction) =>
{
var jobId = connection.ExecuteScalar<long>(
queryString,
queryParameters,
transaction,
commandTimeout: _storage.CommandTimeout).ToString(CultureInfo.InvariantCulture);
var insertParameterSql =
$@"insert into [{_storage.SchemaName}].JobParameter (JobId, Name, Value) values (@jobId, @name, @value)";
using (var commandBatch = new SqlCommandBatch(connection, transaction, preferBatching: _storage.CommandBatchMaxTimeout.HasValue))
{
commandBatch.CommandTimeout = _storage.CommandTimeout;
commandBatch.CommandBatchMaxTimeout = _storage.CommandBatchMaxTimeout;
Thanks. So in a loop, this is prohibitive. I’ll make sure, it is only being executed once every 3 secs or so for a performing UI cancelling button.
1 Like