在 webmethod 上锁定 Task.Run() 不工作 c#?
lock inside a Task.Run() on a webmethod not working c#?
我使用 nhibernate 作为我的 web 服务的 orm,我已经实现了 CustomSqlDriver。我创建 CustomSqlDriver 的原因是因为我需要获取在应用程序中执行的每个查询(及其参数值)并将其保存到数据库中。
每次发生查询(select、更新等)并按相应的顺序调用 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:
任何帮助将不胜感激。
some rows lost order when they gets saved to the db.
Task.Run
不保证任何顺序;项目几乎可以按任何顺序出队,即使它们以正确的顺序出队并安排到不同的线程上,两个线程也可以以不同的方式进行并以不同的顺序获得锁。即使他们以正确的顺序获得锁,我也不认为这是 strict 保证在所有情况下都会保留锁队列顺序 (more reading here) -只是只有一个人有锁。
如果您需要 FIFO:您需要定义该 FIFO 是:某些东西进入可靠的同步队列或列表或类似的顺序。你不能在事后添加 FIFO。
我使用 nhibernate 作为我的 web 服务的 orm,我已经实现了 CustomSqlDriver。我创建 CustomSqlDriver 的原因是因为我需要获取在应用程序中执行的每个查询(及其参数值)并将其保存到数据库中。 每次发生查询(select、更新等)并按相应的顺序调用 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: 任何帮助将不胜感激。
some rows lost order when they gets saved to the db.
Task.Run
不保证任何顺序;项目几乎可以按任何顺序出队,即使它们以正确的顺序出队并安排到不同的线程上,两个线程也可以以不同的方式进行并以不同的顺序获得锁。即使他们以正确的顺序获得锁,我也不认为这是 strict 保证在所有情况下都会保留锁队列顺序 (more reading here) -只是只有一个人有锁。
如果您需要 FIFO:您需要定义该 FIFO 是:某些东西进入可靠的同步队列或列表或类似的顺序。你不能在事后添加 FIFO。