锁定Web方法上的Task.Run()内部无法正常工作c#?

时间:2018-07-03 21:58:12

标签: c# nhibernate concurrency task

im使用nhibernate作为我的Web服务的orm,并且我已经实现了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()中的静态对象上使用锁,并且只要对任何Web方法的调用都是同步的,它就可以工作,但是如果我并行调用它们,则某些行在保存时会丢失顺序到数据库。

我不确定这是否是最好的方法D: 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

  

某些行保存到数据库后失去顺序。

Task.Run不保证有关订单的任何内容;项目可以按几乎任何顺序出队,即使它们以正确的顺序出队并安排在不同的线程上,两个线程也可以以不同的顺序进行处理并以不同的顺序到达锁。即使他们以正确的顺序到达锁定,我也不认为严格保证在所有情况下(more reading here)都将保留锁定队列顺序-仅一个就会有锁。

如果您需要FIFO:您需要定义该FIFO是:某种东西进入可靠的同步队列或列表或类似列表的顺序。事后您不能添加FIFO。