Skip to content

Instantly share code, notes, and snippets.

@restlessmedia
Last active March 8, 2021 09:52
Show Gist options
  • Save restlessmedia/0e80fef6b8ccbc7c91b935a411a5d0f8 to your computer and use it in GitHub Desktop.
Save restlessmedia/0e80fef6b8ccbc7c91b935a411a5d0f8 to your computer and use it in GitHub Desktop.
/// <summary>
/// Creates a connection adapter that cancels any <see cref="IDbCommand"/> created from it when the client disconnects from the response.
/// </summary>
private class ClientDisconnectedConnectionAdapter : IDbConnection
{
private readonly SqlConnection _connection;
public conn(SqlConnection sqlConnection)
{
_connection = sqlConnection ?? throw new ArgumentNullException(nameof(sqlConnection));
}
public string ConnectionString { get => _connection.ConnectionString; set => _connection.ConnectionString = value; }
public int ConnectionTimeout => _connection.ConnectionTimeout;
public string Database => _connection.Database;
public ConnectionState State => _connection.State;
public IDbTransaction BeginTransaction()
{
return _connection.BeginTransaction();
}
public IDbTransaction BeginTransaction(IsolationLevel il)
{
return _connection.BeginTransaction(il);
}
public void ChangeDatabase(string databaseName)
{
_connection.ChangeDatabase(databaseName);
}
public void Close()
{
_connection.Close();
}
public IDbCommand CreateCommand()
{
IDbCommand command = _connection.CreateCommand();
try
{
// context may not be available - there's not a robust way of checking before getting the 'context is unavailable exception'
HttpContext.Current.Response.ClientDisconnectedToken.Register(() =>
{
try
{
// don't break the request if the cancel fails
command.Cancel();
}
catch(Exception e)
{
System.Diagnostics.Trace.TraceError($"Failed to canel db command from http response register ClientDisconnectedToken callback. {e.Message}");
}
});
}
catch(Exception e)
{
System.Diagnostics.Trace.TraceError($"Failed to register callback for db command. {e.Message}");
}
return command;
}
public void Dispose()
{
_connection.Dispose();
}
public void Open()
{
_connection.Open();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment