заблокировать внутри Task.Run () на веб-метод не работает c #? - PullRequest
0 голосов
/ 04 июля 2018

Я использую nhibernate как форму для моих веб-сервисов, и я реализовал CustomSqlDriver. Причина, по которой я создал CustomSqlDriver, заключается в том, что мне нужно получить и сохранить каждый запрос (со значениями их параметров), который выполняется в приложении, в БД. Метод AdjustCommand вызывается каждый раз, когда выполняется запрос (выбор, обновление и т. Д.) И в соответствующем порядке.

public class CustomSqlDriver : SqlClientDriver {
    private static readonly log4net.ILog log = log4net.LogManager.GetLogger("CustomSqlClientDriverLogger");
    private static readonly Object _lock = new Object();

    public override void AdjustCommand(IDbCommand command)
    {
        base.AdjustCommand(command);
        var parameters = (SqlParameterCollection)command.Parameters;

        QueryType queryType = GetQueryType(command);
        string tableName = GetTableName(command.CommandText);
        string fullCommandText = GetFullQuery(command, parameters);

        Task.Run(() =>
        {
            lock (_lock)
            {
                log.Info($"Trying to save the query = {fullCommandText}");
                SaveToDb((int)queryType, fullCommandText, tableName);
            }
        });
    }
}

Мне нужно сохранить каждый запрос по порядку, потому что я буду использовать их позже в другом процессе FIFO Не могу сделать это в том же потоке (потому что это может быть медленным). Как вы можете видеть, я пытался использовать блокировку статического объекта в Task.Run (), и это работает, пока вызов любого веб-метода является синхронным, но если я вызываю их параллельно, некоторые строки теряют порядок, когда они сохраняются в БД

Я не уверен, что это лучший подход. D: Любая помощь будет оценена.

1 Ответ

0 голосов
/ 04 июля 2018

некоторые строки теряют порядок при сохранении в БД.

Task.Run не гарантирует ничего о заказе; элементы могут быть сняты с очереди практически в любом порядке, и даже если они были сняты с очереди в правильном порядке и запланированы на разные потоки, два потока могут проходить по-разному и получать блокировку в разных порядках. Даже если они доберутся до блокировки в правильном порядке, я не думаю, что это строгая гарантия того, что порядок очереди блокировки будет сохранен во всех сценариях ( подробнее здесь ) - только у одного будет блокировка.

Если вам нужен FIFO: вам нужно определить , что FIFO будет: порядок, в котором что-то попадает в надежную синхронную очередь или список или тому подобное. Вы не можете добавить FIFO после факта.

...