未验证 提交 84018880 编写于 作者: S Sam Harwell 提交者: GitHub

Merge pull request #36127 from sharwell/readblob-no-capture

Avoid captures in SqlConnection.ReadBlob
......@@ -129,7 +129,18 @@ public ResettableSqlStatement GetResettableStatement(string query)
return new ResettableSqlStatement(statement);
}
public void RunInTransaction(Action action)
public void RunInTransaction<TState>(Action<TState> action, TState state)
{
RunInTransaction(
state =>
{
state.action(state.state);
return (object)null;
},
(action, state));
}
public TResult RunInTransaction<TState, TResult>(Func<TState, TResult> action, TState state)
{
try
{
......@@ -141,8 +152,9 @@ public void RunInTransaction(Action action)
IsInTransaction = true;
ExecuteCommand("begin transaction");
action();
var result = action(state);
ExecuteCommand("commit transaction");
return result;
}
catch (SqlException ex) when (ex.Result == Result.FULL ||
ex.Result == Result.IOERR ||
......@@ -185,6 +197,7 @@ private void Rollback(bool throwOnError)
public int LastInsertRowId()
=> (int)raw.sqlite3_last_insert_rowid(_handle);
[PerformanceSensitive("https://github.com/dotnet/roslyn/issues/36114", AllowCaptures = false)]
public Stream ReadBlob(string dataTableName, string dataColumnName, long rowId)
{
// NOTE: we do need to do the blob reading in a transaction because of the
......@@ -196,11 +209,9 @@ public Stream ReadBlob(string dataTableName, string dataColumnName, long rowId)
// the one the BLOB handle is open on. Calls to sqlite3_blob_read() and
// sqlite3_blob_write() for an expired BLOB handle fail with a return code of
// SQLITE_ABORT.
Stream stream = null;
RunInTransaction(() =>
{
stream = ReadBlob_InTransaction(dataTableName, dataColumnName, rowId);
});
var stream = RunInTransaction(
state => state.self.ReadBlob_InTransaction(state.dataTableName, state.dataColumnName, state.rowId),
(self: this, dataTableName, dataColumnName, rowId));
return stream;
}
......
......@@ -130,14 +130,16 @@ bool AddStrings(HashSet<string> stringsToAdd)
{
try
{
connection.RunInTransaction(() =>
{
foreach (var value in stringsToAdd)
connection.RunInTransaction(
state =>
{
var id = InsertStringIntoDatabase_MustRunInTransaction(connection, value);
idToString.Object.Add(id, value);
}
});
foreach (var value in state.stringsToAdd)
{
var id = InsertStringIntoDatabase_MustRunInTransaction(state.connection, value);
state.idToString.Object.Add(id, value);
}
},
(stringsToAdd, connection, idToString));
}
catch (SqlException ex) when (ex.Result == Result.CONSTRAINT)
{
......
......@@ -86,10 +86,9 @@ private bool TryFetchStringTable(SqlConnection connection)
// values.
try
{
connection.RunInTransaction(() =>
{
stringId = InsertStringIntoDatabase_MustRunInTransaction(connection, value);
});
stringId = connection.RunInTransaction(
state => InsertStringIntoDatabase_MustRunInTransaction(state.connection, state.value),
(connection, value));
Contract.ThrowIfTrue(stringId == null);
return stringId;
......
......@@ -222,13 +222,15 @@ private async Task FlushAllPendingWritesAsync(CancellationToken cancellationToke
try
{
// Create a transaction and perform all writes within it.
connection.RunInTransaction(() =>
{
foreach (var action in writesToProcess)
connection.RunInTransaction(
state =>
{
action(connection);
}
});
foreach (var action in state.writesToProcess)
{
action(state.connection);
}
},
(writesToProcess, connection));
}
catch (Exception ex)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册